home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992, 1995 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
- /* gdevamiga.c */
- /* Amiga driver for Ghostscript library, requires Kickstart 2.04 or higher */
-
- /* Original development and maintenance up to and including gs3.5.3:
- *
- * Olaf 'Olsen' Barthel
- *
- * Address: Olaf Barthel
- * Brabeckstrasse 35
- * D-30559 Hannover
- * Internet: olsen@sourcery.han.de
- *
- *
- * Current maintenance, libnix integration and 'autoconfiscation':
- *
- * Joop van de Wege
- *
- * Internet: JoopvandeWege@mail.mococo.nl
- *
- *
- * Revised device/size/resolution handling:
- *
- * Steffen Opel
- *
- * Internet: opel@rumms.uni-mannheim.de
- *
- *
- * Couple of changes to compile it with Ghostscript 6.50, PPC
- * changes - note that for PPC I don't call Forbid/Permit but
- * use a global variable because I got crashes otherwise?!?
- *
- * RĂ¼diger Hanke
- *
- * Internet: tomjoad@muenster.de
- */
-
- #include <clib/alib_protos.h>
- #include <clib/macros.h>
- #include <datatypes/pictureclass.h>
- #include <dos/dostags.h>
- #include <dos/rdargs.h>
- #include <dos/var.h>
- #include <dos/dos.h>
- #include <devices/printer.h>
- #include <devices/prtbase.h>
- #include <devices/prtgfx.h>
- #include <exec/errors.h>
- #include <exec/memory.h>
- #include <graphics/displayinfo.h>
- #include <graphics/gfxbase.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/gadgetclass.h>
- #include <intuition/imageclass.h>
- #include <intuition/icclass.h>
- #include <libraries/asl.h>
- #include <libraries/iffparse.h>
-
- #include <proto/asl.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/iffparse.h>
- #include <proto/intuition.h>
- #include <proto/layers.h>
- #include <proto/utility.h>
-
- #ifdef __PPC__
- #include <proto/powerpc.h>
- #include <powerpc/tasksPPC.h>
- #endif
-
- #include "gscdefs.h"
- #include "gserrors.h"
- #include "gx.h" /* for gx_bitmap; includes std.h */
- #include "gxdevice.h"
- #include "gxfixed.h" /* needed for amiga_put_params only */
- #include "gsparam.h"
-
- #include <string.h>
- #include <signal.h>
-
- #ifdef __STORMGCC__
- typedef unsigned int sigset_t;
- #define sigmask(m) (1 << ((m)-1))
- #endif
-
- #ifdef __PPC__
- gx_device *DispatchTaskDevice;
- #endif
-
-
- /* Magic value to compute the resolution from the display database.
- *
- * To compute the dots_per_inch resolution from the ticks_per_pixel
- * resolution in the display database the common base is needed.
- * These base ensures that all Display Modes will be displayed with
- * the same absolute aspect ratio. Don't ask me how the ticks_per_pixel
- * entries are computed exactly, the supplied value has been determined
- * with respect to GfxBase->NormalDisplay[Rows|Columns], some monitors
- * and a meter. Therefore it may be fine tuned to fit any specific
- * monitor/gfx-board environment.
- *
- * TODO: Resolve the constitutional calculation for those entries
- * in the display database!
- */
-
- #define MAGIC_DPI_BASE_VALUE 1447
-
- /* Initial values for resolution and size. */
-
- #define INITIAL_X_DPI 72
- #define INITIAL_Y_DPI 72
-
- #ifdef A4
- /* A4 paper (210mm x 297mm). The dimensions are off by a few nm.... */
- #define INITIAL_WIDTH (int)(8.27 * INITIAL_X_DPI)
- #define INITIAL_HEIGHT (int)(11.7 * INITIAL_Y_DPI)
- #else
- /* U.S. letter paper (8.5" x 11"). */
- #define INITIAL_WIDTH (int)(8.5 * INITIAL_X_DPI)
- #define INITIAL_HEIGHT (int)(11.0 * INITIAL_Y_DPI)
- #endif
-
- /* Default Display Mode. */
-
- #define DEFAULT_DISPLAYMODE ""
-
- /* Default output file name. */
-
- #define DEFAULT_FILENAME "gs_page"
-
- /* Turn a byte into a 24 bit colour value. */
-
- #define SPREAD(i) ((ULONG)(i) << 24 | (ULONG)(i) << 16 | (ULONG)(i) << 8 | (i))
-
- /* Scroller gadget IDs. */
-
- enum { VERTICAL_SCROLLER, HORIZONTAL_SCROLLER,
- UP_ARROW, DOWN_ARROW,
- LEFT_ARROW, RIGHT_ARROW,
-
- GADGET_COUNT
- };
-
- /* Scroller arrow IDs. */
-
- enum { UP_IMAGE, DOWN_IMAGE,
- LEFT_IMAGE, RIGHT_IMAGE,
-
- IMAGE_COUNT
- };
-
- /* Codes for the MoveAround() routine. */
-
- enum { MOVE_MIN,MOVE_FAR_DOWN,MOVE_DOWN,MOVE_UP,MOVE_FAR_UP,MOVE_MAX };
-
- /* Some handy bit masks. */
-
- #define SIG_KILL SIGBREAKF_CTRL_C
- #define SIG_HANDSHAKE SIGF_SINGLE
- #define SIG_WAKEUP SIGBREAKF_CTRL_E
-
- /* Static dimensions of scroller arrows. */
-
- #define ARROW_WIDTH 16
- #define ARROW_HEIGHT 11
-
- /* The `Help' key raw code. */
-
- #define HELP_CODE 95
-
- /* Minimum window inner area dimension. */
-
- #define MINIMUM_WIDTH 64
- #define MINIMUM_HEIGHT 32
-
- /* Handy superbitmap window macros. */
-
- #define LAYERXOFFSET(w) ((w) -> RPort -> Layer -> Scroll_X)
- #define LAYERYOFFSET(w) ((w) -> RPort -> Layer -> Scroll_Y)
-
- /* User input to listen to. */
-
- #define IDCMP_FLAGS (IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_MOUSEMOVE | IDCMP_NEWSIZE | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_RAWKEY)
-
- /* Chunk IDs. */
-
- #define ID_ANNO MAKE_ID('A','N','N','O')
- #define ID_DPI MAKE_ID('D','P','I',' ')
-
- typedef struct
- {
- UWORD dpi_x;
- UWORD dpi_y;
- } DPIHeader;
-
- /* Packer modes. */
-
- #define DUMP 0
- #define RUN 1
-
- /* Minimum data run size, maximum data run size and maximum cache size. */
-
- #define MINRUN 3
- #define MAXRUN 128
- #define MAXDAT 128
-
- /* This module actually implements four different Amiga based
- * devices. As the rendering operations are all the same,
- * one single device definition is sufficient.
- */
-
- typedef struct gx_device_amiga
- {
- gx_device_common;
-
- struct Screen *screen; /* Any screen */
- struct Window *window; /* Some window to be opened on the Workbench screen */
-
- struct BitMap *super_bitmap; /* Window superbitmap area */
- struct Gadget **gadget; /* Scroller gadgets */
- struct Image **image; /* Scroller arrow images */
-
- struct Task *dispatcher; /* Slider dispatch task */
- struct Process *main; /* Main program */
-
- struct RastPort *rport; /* Rendering area */
-
- struct IODRPReq *printer; /* Printer interface data */
- struct MsgPort *port; /* Printer io data */
-
- struct ColorMap *colormap; /* A black/white colour map */
- struct BitMap *bitmap; /* Rendering bitmap data */
- PLANEPTR bitplane; /* Rendering raster */
-
- gx_color_index last_pen; /* The last colour set */
-
- char display_mode[DISPLAYNAMELEN + 1]; /* The Display Mode */
- char file_name[256];/* The output file name */
- int page_count; /* The page number counter */
-
- int cube_size; /* Colour cube size, 0 for b/w */
- struct RastPort *temp_rport; /* Temporary raster port for pixmap imaging. */
- UBYTE *temp_array; /* Temporary colour manipulation array. */
- LONG *pens;
- } gx_device_amiga;
-
- /* Cheap, but effective macro for casting the device argument ;-) */
-
- #define xdev ((gx_device_amiga *)dev)
-
- /* Support functions */
-
- private int amiga_open(gx_device *dev, ULONG Mode);
- private VOID set_mono_device(gx_device_amiga *dev);
- private VOID set_colour_device(gx_device_amiga *dev, int cube_size,
- LONG *pens);
- private VOID set_colour_printer_device(gx_device_amiga *dev, LONG CubeSize);
- private LONG * AllocatePens(struct ViewPort *VPort, LONG CubeSize);
- private VOID DeleteBitMap(struct BitMap *BitMap, BOOL Private);
- private struct BitMap * CreateBitMap(LONG Width, LONG Height, LONG Depth,
- ULONG Flags, struct BitMap *Friend, BOOL Private);
- private VOID DeleteTempRPort(struct RastPort *Temp);
- private struct RastPort * CreateTempRPort(struct RastPort *Source);
- private LONG Euclid(LONG a, LONG b);
- private BYTE * PutDump(register BYTE *Destination, register LONG Count);
- private BYTE * PutRun(register BYTE *Destination, LONG Count, WORD Char);
- private LONG PackRow(PLANEPTR *SourcePtr, register BYTE *Destination,
- LONG RowSize);
- private BOOL PutBODY(struct IFFHandle *Handle, struct BitMap *BitMap);
- private BOOL PutANNO(struct IFFHandle *Handle);
- private BOOL PutCAMG(struct IFFHandle *Handle);
- private BOOL PutCMAP(struct IFFHandle *Handle);
- private BOOL PutDPI(struct IFFHandle *Handle, UWORD X_DPI, UWORD Y_DPI);
- private BOOL PutBMHD(struct IFFHandle *Handle, LONG Width, LONG Height,
- UWORD X_DPI, UWORD Y_DPI);
- private BOOL SaveBitMap(STRPTR Name, struct BitMap *BitMap, LONG Width,
- LONG Height, UWORD X_DPI, UWORD Y_DPI);
- private VOID DispatchTask(VOID);
- private VOID DeleteScrollers(gx_device *dev);
- private BOOL CreateScrollers(gx_device *dev, struct Screen *Screen);
- private VOID WindowResize(gx_device *dev);
- private VOID WindowUpdate(struct Gadget *Gadget, gx_device *dev);
- private VOID MoveAround(struct Gadget *Gadget, LONG How, gx_device *dev);
- private VOID DispatchSuperWindow(gx_device *dev);
- private VOID PrintPrinterError(const char *header, LONG io_Error);
- void devcleanup(VOID);
-
- /* Device procedures (see gxdevice.h for the definitions) */
-
- private dev_proc_open_device(amiga_open_default);
- private dev_proc_open_device(amiga_open_custom);
- private dev_proc_open_device(amiga_open_printer);
- private dev_proc_open_device(amiga_open_ilbm);
- private dev_proc_output_page(amiga_output_page);
- private dev_proc_output_page(amiga_output_page_printer);
- private dev_proc_output_page(amiga_output_page_ilbm);
- private dev_proc_close_device(amiga_close);
- private dev_proc_close_device(amiga_close_printer);
- private dev_proc_close_device(amiga_close_ilbm);
- private dev_proc_map_rgb_color(amiga_map_rgb_color);
- private dev_proc_map_rgb_color(amiga_color_map_rgb_color);
- private dev_proc_map_rgb_color(amiga_color_map_rgb_color_pen);
- private dev_proc_map_color_rgb(amiga_map_color_rgb);
- private dev_proc_map_color_rgb(amiga_color_map_color_rgb);
- private dev_proc_map_color_rgb(amiga_color_map_color_rgb_pen);
- private dev_proc_fill_rectangle(amiga_fill_rectangle);
- private dev_proc_fill_rectangle(amiga_fill_rectangle_raw);
- private dev_proc_fill_rectangle(amiga_fill_rectangle_raw_color);
- private dev_proc_copy_mono(amiga_copy_mono);
- private dev_proc_copy_mono(amiga_copy_mono_raw);
- private dev_proc_copy_mono(amiga_copy_mono_raw_color);
- private dev_proc_copy_color(amiga_copy_color);
- private dev_proc_copy_color(amiga_copy_color_raw);
- private dev_proc_copy_color(amiga_copy_color8);
- private dev_proc_copy_color(amiga_copy_color_raw_color16);
- private dev_proc_draw_line(amiga_draw_line);
- private dev_proc_draw_line(amiga_draw_line_raw);
- private dev_proc_draw_line(amiga_draw_line_raw_color);
- private dev_proc_get_bits(amiga_get_bits);
- private dev_proc_get_params(amiga_get_params);
- private dev_proc_put_params(amiga_put_params);
-
- /* External reference to some libraries, required for version checking, etc. */
-
- extern struct GfxBase *GfxBase;
- extern struct Library *AslBase;
-
- /* Detect wether user has set -g and/or -r at the command line */
-
- private BOOL ResolutionSwitch = FALSE;
- private BOOL GeometrySwitch = FALSE;
-
- /* Number of packed bytes and pack buffer. */
-
- private LONG PackedBytes;
- private BYTE Buffer[MAXDAT + 1];
-
- /* Bit masks. */
-
- private UBYTE shift[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
- private UBYTE masks[8] = { 127,191,223,239,247,251,253,254 };
-
- /* Dark (black) and light (white) rendering colours; the default device
- * determines the actual colours to be used by looking into the screen
- * colour lookup table, the other device drivers leave these values
- * untouched.
- */
-
- private UBYTE DarkPen = 0;
- private UBYTE LightPen = 1;
-
- /* Device routine jump tables */
-
- private gx_device_procs amiga_default_procs =
- {
- amiga_open_default,
- NULL, /* get_initial_matrix */
- NULL, /* sync_output */
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- NULL, /* tile_rectangle */
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- NULL, /* get_bits */
- amiga_get_params,
- amiga_put_params,
- NULL, /* map_cmyk_color */
- NULL, /* get_xfont_procs */
- NULL, /* get_xfont_device */
- NULL, /* map_rgb_alpha_color */
- gx_page_device_get_page_device, /* get_page_device */
- NULL, /* get_alpha_bits */
- NULL, /* copy_alpha */
- NULL, /* get_band */
- NULL, /* copy_rop */
- NULL, /* fill_path */
- NULL, /* stroke_path */
- NULL, /* fill_mask */
- NULL, /* fill_trapezoid */
- NULL, /* fill_parallelogram */
- NULL, /* fill_triangle */
- NULL, /* draw_thin_line */
- NULL, /* begin_image */
- NULL, /* image_data */
- NULL, /* end_image */
- NULL, /* strip_tile_rectangle */
- NULL, /* strip_copy_rop */
- };
-
- private gx_device_procs amiga_custom_procs =
- {
- amiga_open_custom,
- NULL, /* get_initial_matrix */
- NULL, /* sync_output */
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- NULL, /* tile_rectangle */
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- NULL, /* get_bits */
- amiga_get_params,
- amiga_put_params,
- NULL, /* map_cmyk_color */
- NULL, /* get_xfont_procs */
- NULL, /* get_xfont_device */
- NULL, /* map_rgb_alpha_color */
- gx_page_device_get_page_device, /* get_page_device */
- NULL, /* get_alpha_bits */
- NULL, /* copy_alpha */
- NULL, /* get_band */
- NULL, /* copy_rop */
- NULL, /* fill_path */
- NULL, /* stroke_path */
- NULL, /* fill_mask */
- NULL, /* fill_trapezoid */
- NULL, /* fill_parallelogram */
- NULL, /* fill_triangle */
- NULL, /* draw_thin_line */
- NULL, /* begin_image */
- NULL, /* image_data */
- NULL, /* end_image */
- NULL, /* strip_tile_rectangle */
- NULL, /* strip_copy_rop */
- };
-
- private gx_device_procs amiga_printer_procs =
- {
- amiga_open_printer,
- NULL, /* get_initial_matrix */
- NULL, /* sync_output */
- amiga_output_page_printer,
- amiga_close_printer,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle_raw,
- NULL, /* tile_rectangle */
- amiga_copy_mono_raw,
- amiga_copy_color_raw,
- amiga_draw_line_raw,
- amiga_get_bits,
- amiga_get_params,
- amiga_put_params,
- NULL, /* map_cmyk_color */
- NULL, /* get_xfont_procs */
- NULL, /* get_xfont_device */
- NULL, /* map_rgb_alpha_color */
- gx_page_device_get_page_device, /* get_page_device */
- NULL, /* get_alpha_bits */
- NULL, /* copy_alpha */
- NULL, /* get_band */
- NULL, /* copy_rop */
- NULL, /* fill_path */
- NULL, /* stroke_path */
- NULL, /* fill_mask */
- NULL, /* fill_trapezoid */
- NULL, /* fill_parallelogram */
- NULL, /* fill_triangle */
- NULL, /* draw_thin_line */
- NULL, /* begin_image */
- NULL, /* image_data */
- NULL, /* end_image */
- NULL, /* strip_tile_rectangle */
- NULL, /* strip_copy_rop */
- };
-
- private gx_device_procs amiga_ilbm_procs =
- {
- amiga_open_ilbm,
- NULL, /* get_initial_matrix */
- NULL, /* sync_output */
- amiga_output_page_ilbm,
- amiga_close_ilbm,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle_raw,
- NULL, /* tile_rectangle */
- amiga_copy_mono_raw,
- amiga_copy_color_raw,
- amiga_draw_line_raw,
- amiga_get_bits,
- amiga_get_params,
- amiga_put_params,
- NULL, /* map_cmyk_color */
- NULL, /* get_xfont_procs */
- NULL, /* get_xfont_device */
- NULL, /* map_rgb_alpha_color */
- gx_page_device_get_page_device, /* get_page_device */
- NULL, /* get_alpha_bits */
- NULL, /* copy_alpha */
- NULL, /* get_band */
- NULL, /* copy_rop */
- NULL, /* fill_path */
- NULL, /* stroke_path */
- NULL, /* fill_mask */
- NULL, /* fill_trapezoid */
- NULL, /* fill_parallelogram */
- NULL, /* fill_triangle */
- NULL, /* draw_thin_line */
- NULL, /* begin_image */
- NULL, /* image_data */
- NULL, /* end_image */
- NULL, /* strip_tile_rectangle */
- NULL, /* strip_copy_rop */
- };
-
- /* Default device: opens a window on the Workbench screen and renders into it */
-
- gx_device_amiga gs_amiga_device =
- {
- std_device_std_body(gx_device_amiga, &amiga_default_procs, "amiga",
- INITIAL_WIDTH, INITIAL_HEIGHT, INITIAL_X_DPI, INITIAL_Y_DPI),
- { 0 }, /* std_procs */
-
- NULL, /* screen */
- NULL, /* window */
-
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_DISPLAYMODE, /* display_mode */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Custom device: opens a custom screen, will ask for screen mode or check env variable. */
-
- gx_device_amiga gs_amiga_custom_device =
- {
- std_device_std_body(gx_device_amiga, &amiga_custom_procs, "amiga_custom",
- INITIAL_WIDTH, INITIAL_HEIGHT, INITIAL_X_DPI, INITIAL_Y_DPI),
- { 0 }, /* std_procs */
-
- NULL, /* screen */
- NULL, /* window */
-
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_DISPLAYMODE, /* display_mode */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Printer device: renders the imagery and sends it to the printer */
-
- gx_device_amiga gs_amiga_printer_device =
- {
- std_device_std_body(gx_device_amiga, &amiga_printer_procs, "amiga_printer",
- INITIAL_WIDTH, INITIAL_HEIGHT, INITIAL_X_DPI, INITIAL_Y_DPI),
- { 0 }, /* std_procs */
-
- NULL, /* screen */
- NULL, /* window */
-
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_DISPLAYMODE, /* display_mode */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* ILBM device: renders the imagery and saves it to an IFF-ILBM file. */
-
- gx_device_amiga gs_amiga_ilbm_device =
- {
- std_device_std_body(gx_device_amiga, &amiga_ilbm_procs, "amiga_ilbm",
- INITIAL_WIDTH, INITIAL_HEIGHT, INITIAL_X_DPI, INITIAL_Y_DPI),
- { 0 }, /* std_procs */
-
- NULL, /* screen */
- NULL, /* window */
-
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_DISPLAYMODE, /* display_mode */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* set_mono_device(gx_device_amiga *dev,int cube_size,LONG *pens):
- *
- * Reconfigure a device for monochrome output.
- */
-
- private VOID
- set_mono_device(gx_device_amiga *dev)
- {
- xdev -> color_info . num_components = 1;
- xdev -> color_info . depth = 1;
- xdev -> color_info . max_gray = 1;
- xdev -> color_info . max_color = 0;
- xdev -> color_info . dither_grays = 2;
- xdev -> color_info . dither_colors = 0;
-
- set_dev_proc( xdev, copy_color, amiga_copy_color );
- set_dev_proc( xdev, map_rgb_color, amiga_map_rgb_color );
- set_dev_proc( xdev, map_color_rgb, amiga_map_color_rgb );
-
- /* xdev -> std_procs . copy_color = amiga_copy_color;
- xdev -> std_procs . map_rgb_color = amiga_map_rgb_color;
- xdev -> std_procs . map_color_rgb = amiga_map_color_rgb;*/
-
- xdev -> cube_size = 0;
- }
-
- /* set_colour_device(gx_device_amiga *dev,int cube_size,LONG *pens):
- *
- * Reconfigure a device for colour output.
- */
-
- private VOID
- set_colour_device(gx_device_amiga *dev,int cube_size,LONG *pens)
- {
- xdev -> color_info . num_components = 3;
- xdev -> color_info . depth = 8;
- xdev -> color_info . max_gray = cube_size - 1;
- xdev -> color_info . max_color = cube_size - 1;
- xdev -> color_info . dither_grays = cube_size;
- xdev -> color_info . dither_colors = cube_size;
-
- set_dev_proc( xdev, copy_color, amiga_copy_color8 );
- // xdev -> std_procs . copy_color = amiga_copy_color8;
-
- /* Any colours to be remapped? */
-
- if(pens)
- {
- set_dev_proc( xdev, map_rgb_color, amiga_color_map_rgb_color_pen );
- set_dev_proc( xdev, map_color_rgb, amiga_color_map_color_rgb_pen );
-
- // xdev -> std_procs . map_rgb_color = amiga_color_map_rgb_color_pen;
- // xdev -> std_procs . map_color_rgb = amiga_color_map_color_rgb_pen;
- xdev -> pens = pens;
- }
- else
- {
- set_dev_proc( xdev, map_rgb_color, amiga_color_map_rgb_color );
- set_dev_proc( xdev, map_color_rgb, amiga_color_map_color_rgb );
-
- // xdev -> std_procs . map_rgb_color = amiga_color_map_rgb_color;
- // xdev -> std_procs . map_color_rgb = amiga_color_map_color_rgb;
- }
-
- /* Remember the size of the RGB cube. */
-
- xdev -> cube_size = cube_size;
- }
-
- /* set_colour_printer_device(gx_device_amiga *dev,LONG CubeSize):
- *
- * Configure the printer device for colour output.
- */
-
- private VOID
- set_colour_printer_device(gx_device_amiga *dev,LONG CubeSize)
- {
- xdev -> color_info . num_components = 3;
- xdev -> color_info . depth = 16;
- xdev -> color_info . max_gray = CubeSize - 1;
- xdev -> color_info . max_color = CubeSize - 1;
- xdev -> color_info . dither_grays = CubeSize;
- xdev -> color_info . dither_colors = CubeSize;
-
- set_dev_proc( xdev, fill_rectangle, amiga_fill_rectangle_raw_color );
- set_dev_proc( xdev, copy_mono, amiga_copy_mono_raw_color );
- set_dev_proc( xdev, copy_color, amiga_copy_color_raw_color16 );
- set_dev_proc( xdev, map_rgb_color, amiga_color_map_rgb_color );
- set_dev_proc( xdev, map_color_rgb, amiga_color_map_color_rgb );
- /* xdev -> std_procs . fill_rectangle = amiga_fill_rectangle_raw_color;
- xdev -> std_procs . copy_mono = amiga_copy_mono_raw_color;
- xdev -> std_procs . copy_color = amiga_copy_color_raw_color16;
- xdev -> std_procs . draw_line = amiga_draw_line_raw_color;
- xdev -> std_procs . map_rgb_color = amiga_color_map_rgb_color;
- xdev -> std_procs . map_color_rgb = amiga_color_map_color_rgb;*/
- xdev -> cube_size = CubeSize;
- }
-
- /* DeleteBitMap(struct BitMap *BitMap,BOOL Private):
- *
- * Free memory associated with a custom rendering bitmap.
- */
-
- private VOID
- DeleteBitMap(struct BitMap *BitMap,BOOL Private)
- {
- if(GfxBase -> LibNode . lib_Version >= 39 && !Private)
- FreeBitMap(BitMap);
- else
- {
- LONG i;
-
- for(i = 0 ; i < BitMap -> Depth ; i++)
- {
- if(BitMap -> Planes[i])
- FreeVec(BitMap -> Planes[i]);
- }
-
- FreeVec(BitMap);
- }
- }
-
- /* CreateBitMap(LONG Width,LONG Height,LONG Depth,ULONG Flags,struct BitMap *Friend,BOOL Private):
- *
- * Create a custom rendering bitmap.
- */
-
- private struct BitMap *
- CreateBitMap(LONG Width,LONG Height,LONG Depth,ULONG Flags,struct BitMap *Friend,BOOL Private)
- {
- if(GfxBase -> LibNode . lib_Version >= 39 && !Private)
- return(AllocBitMap(Width,Height,Depth,Flags,Friend));
- else
- {
- struct BitMap *BitMap;
- LONG Plus;
- ULONG MemType;
-
- /* Bitmap structure needs to be padded if more
- * than the standard eight bitplanes are to be
- * allocated.
- */
-
- if(Depth > 8)
- Plus = (Depth - 8) * sizeof(PLANEPTR);
- else
- Plus = 0;
-
- if(Private)
- MemType = MEMF_ANY;
- else
- MemType = MEMF_CHIP;
-
- BitMap = (struct BitMap *)AllocVec(sizeof(struct BitMap) + Plus,
- MEMF_ANY | MEMF_CLEAR);
- if(BitMap)
- {
- LONG i,PageSize;
-
- InitBitMap(BitMap,Depth,Width,Height);
-
- PageSize = BitMap -> BytesPerRow * BitMap -> Rows;
-
- for(i = 0 ; i < BitMap -> Depth ; i++)
- {
- if(!(BitMap -> Planes[i] = (PLANEPTR)AllocVec(PageSize,MemType)))
- {
- LONG j;
-
- for(j = 0 ; j < i ; j++)
- FreeVec(BitMap -> Planes[j]);
-
- FreeVec(BitMap);
-
- return(NULL);
- }
- }
-
- return(BitMap);
- }
- else
- {
- return(NULL);
- }
- }
- }
-
- /* DeleteTempRPort(struct RastPort *Temp):
- *
- * Free memory associated with a temporary raster port.
- */
-
- private VOID
- DeleteTempRPort(struct RastPort *Temp)
- {
- DeleteBitMap(Temp -> BitMap,FALSE);
-
- FreeVec(Temp);
- }
-
- /* CreateTempRPort(struct RastPort *Source):
- *
- * Allocate memory for temporary raster port (one line high).
- */
-
- private struct RastPort *
- CreateTempRPort(struct RastPort *Source)
- {
- struct RastPort *Temp;
-
- Temp = (struct RastPort *)AllocVec(sizeof(struct RastPort), MEMF_ANY);
- if(Temp)
- {
- LONG Width,Depth;
-
- CopyMem(Source,Temp,sizeof(struct RastPort));
-
- Temp -> Layer = NULL;
-
- if(GfxBase -> LibNode . lib_Version >= 39)
- {
- Width = GetBitMapAttr(Source -> BitMap,BMA_WIDTH);
- Depth = GetBitMapAttr(Source -> BitMap,BMA_DEPTH);
- }
- else
- {
- Width = Source -> BitMap -> BytesPerRow * 8;
- Depth = Source -> BitMap -> Depth;
- }
-
- Temp->BitMap = CreateBitMap(Width, 1, Depth, NULL, Source->BitMap,
- FALSE);
- if(Temp -> BitMap)
- return(Temp);
- else
- FreeVec(Temp);
- }
-
- return(NULL);
- }
-
- /* Euclid(LONG a,LONG b):
- *
- * Compute the greatest common divisor of two integers.
- */
-
- private LONG
- Euclid(LONG a,LONG b)
- {
- do
- {
- if(a < b)
- {
- LONG t;
-
- t = a;
- a = b;
- b = t;
- }
-
- a = a % b;
- }
- while(a);
-
- return(b);
- }
-
- /* PutDump(register BYTE *Destination,register LONG Count):
- *
- * Store a byte dump.
- */
-
- private BYTE *
- PutDump(register BYTE *Destination,register LONG Count)
- {
- register BYTE *Source = Buffer;
-
- *Destination++ = Count - 1;
- PackedBytes += Count + 1;
-
- while(Count--)
- *Destination++ = *Source++;
-
- return(Destination);
- }
-
- /* PutRun(register BYTE *Destination,LONG Count,WORD Char):
- *
- * Store a byte run.
- */
-
- private BYTE *
- PutRun(register BYTE *Destination,LONG Count,WORD Char)
- {
- *Destination++ = -(Count - 1);
- *Destination++ = Char;
- PackedBytes += 2;
-
- return(Destination);
- }
-
- /* PackRow(PLANEPTR *SourcePtr,register BYTE *Destination,LONG RowSize):
- *
- * Pack a raster line using the CmpByteRun1 algorithm.
- */
-
- private LONG
- PackRow(PLANEPTR *SourcePtr,register BYTE *Destination,LONG RowSize)
- {
- register BYTE *Source = *SourcePtr;
-
- WORD Buffered = 1,
- RunStart = 0;
- BYTE Mode = DUMP,
- LastChar,
- Char;
-
- PackedBytes = 0;
-
- Buffer[0] = LastChar = Char = *Source++;
-
- RowSize--;
-
- while(RowSize--)
- {
- Buffer[Buffered++] = Char = *Source++;
-
- if(Mode)
- {
- if((Char != LastChar) || (Buffered - RunStart > MAXRUN))
- {
- Destination = PutRun(Destination,Buffered - 1 - RunStart,LastChar);
- Buffer[0] = Char;
- Buffered = 1;
- RunStart = 0;
- Mode = DUMP;
- }
- }
- else
- {
- if(Buffered > MAXDAT)
- {
- Destination = PutDump(Destination,Buffered - 1);
- Buffer[0] = Char;
- Buffered = 1;
- RunStart = 0;
- }
- else
- {
- if(Char == LastChar)
- {
- if(Buffered - RunStart >= MINRUN)
- {
- if(RunStart)
- Destination = PutDump(Destination,RunStart);
-
- Mode = RUN;
- }
- else
- {
- if(!RunStart)
- Mode = RUN;
- }
- }
- else
- RunStart = Buffered - 1;
- }
- }
-
- LastChar = Char;
- }
-
- if(Mode)
- PutRun(Destination,Buffered - RunStart,LastChar);
- else
- PutDump(Destination,Buffered);
-
- *SourcePtr = Source;
-
- return(PackedBytes);
- }
-
- /* PutBODY(struct IFFHandle *Handle,struct BitMap *BitMap):
- *
- * Store a bitmap in a BODY chunk.
- */
-
- private BOOL
- PutBODY(struct IFFHandle *Handle,struct BitMap *BitMap)
- {
- PLANEPTR *Planes;
- BYTE *PackBuffer;
- BOOL Success = FALSE;
- LONG PackedBytes,
- i,j;
-
- /* Allocate the bitplane information. */
-
- Planes = (PLANEPTR *)AllocVec(BitMap->Depth * sizeof(PLANEPTR *),
- MEMF_ANY | MEMF_CLEAR);
- if(Planes)
- {
- /* Allocate the compression buffer. */
-
- PackBuffer = (BYTE *)AllocVec(BitMap->BytesPerRow * 2, MEMF_ANY);
- if(PackBuffer)
- {
- /* Copy the planes over. */
-
- for(i = 0 ; i < BitMap -> Depth ; i++)
- Planes[i] = BitMap -> Planes[i];
-
- if(!PushChunk(Handle,0,ID_BODY,IFFSIZE_UNKNOWN))
- {
- Success = TRUE;
-
- /* Run down the rows. */
-
- for(i = 0 ; Success && i < BitMap -> Rows ; i++)
- {
- for(j = 0 ; Success && j < BitMap -> Depth ; j++)
- {
- /* Pack the data. */
-
- PackedBytes = PackRow(&Planes[j],PackBuffer,BitMap -> BytesPerRow);
-
- /* Write it to disk. */
-
- if(WriteChunkRecords(Handle,PackBuffer,PackedBytes,1) != 1)
- Success = FALSE;
- }
- }
-
- if(PopChunk(Handle))
- Success = FALSE;
- }
-
- FreeVec(PackBuffer);
- }
-
- FreeVec(Planes);
- }
-
- return(Success);
- }
-
- /* PutANNO(struct IFFHandle *Handle):
- *
- * Store annotation chunk.
- */
-
- private BOOL
- PutANNO(struct IFFHandle *Handle)
- {
- STATIC unsigned char Note[256];
-
- sprintf(Note, "Image generated by %s %d.%02d (device=amiga_ilbm)",
- gs_product, (int)(gs_revision / 100), (int)(gs_revision % 100));
-
- if(!PushChunk(Handle,0,ID_ANNO,strlen(Note)))
- {
- if(WriteChunkRecords(Handle,Note,strlen(Note),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutCAMG(struct IFFHandle *Handle):
- *
- * Store display mode chunk.
- */
-
- private BOOL
- PutCAMG(struct IFFHandle *Handle)
- {
- ULONG ViewModes = HIRESLACE_KEY;
-
- if(!PushChunk(Handle,0,ID_CAMG,sizeof(ULONG)))
- {
- if(WriteChunkRecords(Handle,&ViewModes,sizeof(ULONG),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutCMAP(struct IFFHandle *Handle):
- *
- * Store colour map chunk.
- */
-
- private BOOL
- PutCMAP(struct IFFHandle *Handle)
- {
- STATIC UBYTE Colours[2][3] =
- {
- { 0x00,0x00,0x00, },
- { 0xFF,0xFF,0xFF, },
- };
-
- if(!PushChunk(Handle,0,ID_CMAP,sizeof(Colours)))
- {
- if(WriteChunkRecords(Handle,Colours,2,3) == 3)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutDPI(struct IFFHandle *Handle,UWORD X_DPI,UWORD Y_DPI):
- *
- * Store DPI chunk.
- */
-
- private BOOL
- PutDPI(struct IFFHandle *Handle,UWORD X_DPI,UWORD Y_DPI)
- {
- DPIHeader Header;
-
- Header . dpi_x = X_DPI;
- Header . dpi_y = Y_DPI;
-
- if(!PushChunk(Handle,0,ID_DPI,sizeof(Header)))
- {
- if(WriteChunkRecords(Handle,&Header,sizeof(Header),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutBMHD(struct IFFHandle *Handle,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI):
- *
- * Store BMHD chunk.
- */
-
- private BOOL
- PutBMHD(struct IFFHandle *Handle,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI)
- {
- /* Valid parameters? */
-
- if(X_DPI > 0 && Y_DPI > 0 && Width > 0 && Height > 0)
- {
- struct BitMapHeader Header;
- UWORD gcd;
-
- /* So we can store neat & small
- * aspect ration values.
- */
-
- gcd = Euclid(X_DPI,Y_DPI);
-
- Header . bmh_Width = Width;
- Header . bmh_Height = Height;
- Header . bmh_Left = 0;
- Header . bmh_Top = 0;
- Header . bmh_Depth = 1;
- Header . bmh_Masking = 0;
- Header . bmh_Compression = 1;
- Header . bmh_Pad = 0;
- Header . bmh_Transparent = 0;
- Header . bmh_XAspect = X_DPI / gcd;
- Header . bmh_YAspect = Y_DPI / gcd;
- Header . bmh_PageWidth = Width;
- Header . bmh_PageHeight = Height;
-
- if(!PushChunk(Handle,0,ID_BMHD,sizeof(Header)))
- {
- if(WriteChunkRecords(Handle,&Header,sizeof(Header),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
- }
-
- return(FALSE);
- }
-
- /* SaveBitMap(STRPTR Name,struct BitMap *BitMap,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI):
- *
- * Store a bitmap in an IFF-ILBM file.
- */
-
- private BOOL
- SaveBitMap(STRPTR Name,struct BitMap *BitMap,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI)
- {
- struct IFFHandle *Handle;
- BOOL Success = FALSE;
-
- Handle = AllocIFF();
- if(Handle)
- {
- Handle -> iff_Stream = Open(Name, MODE_NEWFILE);
- if(Handle)
- {
- InitIFFasDOS(Handle);
-
- if(!OpenIFF(Handle,IFFF_WRITE))
- {
- if(!PushChunk(Handle,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN))
- {
- if(PutBMHD(Handle,Width,Height,X_DPI,Y_DPI))
- {
- if(PutANNO(Handle))
- {
- if(PutCMAP(Handle))
- {
- if(PutCAMG(Handle))
- {
- if(PutDPI(Handle,X_DPI,Y_DPI))
- {
- if(PutBODY(Handle,BitMap))
- Success = TRUE;
- }
- }
- }
- }
- }
-
- if(PopChunk(Handle))
- Success = FALSE;
- }
-
- CloseIFF(Handle);
- }
-
- Close(Handle -> iff_Stream);
-
- if(!Success)
- DeleteFile(Name);
- }
-
- FreeIFF(Handle);
- }
-
- return(Success);
- }
-
- /* DispatchTask():
- *
- * Asynchronous window message dispatcher.
- */
-
- private VOID
- DispatchTask()
- {
- struct Task *me;
- gx_device *dev;
-
- /* Set up global data area base register. */
- #ifdef IXEMUL
- ix_geta4();
- #endif
- /* Who am I? */
- me = FindTask(NULL);
-
- #ifdef __PPC__
- dev = DispatchTaskDevice;
- #else
- /* Wait for wakeup call. */
-
- Wait(SIG_WAKEUP);
-
- /* Obtain device pointer. */
-
- dev = me -> tc_UserData;
- #endif
-
- /* Enable user input. */
-
- if(ModifyIDCMP(xdev -> window,IDCMP_FLAGS))
- {
- ULONG Mask = 1 << xdev -> window -> UserPort -> mp_SigBit,
- Set;
- BOOL Done = FALSE;
-
- /* Fill in the dispatcher entry. */
-
- xdev -> dispatcher = me;
-
- /* Ring back. */
-
- Signal((struct Task *)xdev -> main,SIG_HANDSHAKE);
-
- /* Wait for input... */
-
- do
- {
- Set = Wait(Mask | SIG_KILL);
-
- if(Set & Mask)
- DispatchSuperWindow(dev);
-
- if(Set & SIG_KILL)
- Done = TRUE;
- }
- while(!Done);
-
- /* Disable user input. */
-
- ModifyIDCMP(xdev -> window,NULL);
- }
-
- #ifndef __PPC__
- /* Disable task switching. */
-
- Forbid();
-
- /* Clear the dispatcher entry. */
-
- xdev -> dispatcher = NULL;
-
- /* Signal the main process that we are done. */
-
- Signal((struct Task *)xdev -> main,SIG_HANDSHAKE);
-
- /* Enable task switching. */
-
- Permit();
- #endif
-
- /* Remove ourselves. */
-
- RemTask(NULL);
- }
-
- /* DeleteScrollers(gx_device *dev):
- *
- * Delete the window border scrollers.
- */
-
- private VOID
- DeleteScrollers(gx_device *dev)
- {
- if(xdev -> gadget)
- {
- if(xdev -> gadget[HORIZONTAL_SCROLLER])
- DisposeObject(xdev -> gadget[HORIZONTAL_SCROLLER]);
-
- if(xdev -> gadget[VERTICAL_SCROLLER])
- DisposeObject(xdev -> gadget[VERTICAL_SCROLLER]);
-
- if(xdev -> gadget[UP_ARROW])
- DisposeObject(xdev -> gadget[UP_ARROW]);
-
- if(xdev -> gadget[DOWN_ARROW])
- DisposeObject(xdev -> gadget[DOWN_ARROW]);
-
- if(xdev -> gadget[LEFT_ARROW])
- DisposeObject(xdev -> gadget[LEFT_ARROW]);
-
- if(xdev -> gadget[RIGHT_ARROW])
- DisposeObject(xdev -> gadget[RIGHT_ARROW]);
-
- FreeVec(xdev -> gadget);
-
- xdev -> gadget = NULL;
- }
-
- if(xdev -> image)
- {
- if(xdev -> image[UP_IMAGE])
- DisposeObject(xdev -> image[UP_IMAGE]);
-
- if(xdev -> image[DOWN_IMAGE])
- DisposeObject(xdev -> image[DOWN_IMAGE]);
-
- if(xdev -> image[LEFT_IMAGE])
- DisposeObject(xdev -> image[LEFT_IMAGE]);
-
- if(xdev -> image[RIGHT_IMAGE])
- DisposeObject(xdev -> image[RIGHT_IMAGE]);
-
- FreeVec(xdev -> image);
-
- xdev -> image = NULL;
- }
- }
-
- /* CreateScrollers(gx_device *dev,struct Screen *Screen):
- *
- * Create the window border scroller handles.
- */
-
- private BOOL
- CreateScrollers(gx_device *dev,struct Screen *Screen)
- {
- BOOL Result = FALSE;
-
- xdev -> gadget = (struct Gadget **)AllocVec(sizeof(struct Gadget *)
- * GADGET_COUNT, MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC);
- if(xdev -> gadget)
- {
- xdev -> image = (struct Image **)AllocVec(sizeof(struct Image *)
- * IMAGE_COUNT, MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC);
- if(xdev -> image)
- {
- struct DrawInfo *DrawInfo;
-
- DrawInfo = GetScreenDrawInfo(Screen);
- if(DrawInfo)
- {
- ULONG SizeWidth,
- SizeHeight;
- ULONG ArrowWidth,
- ArrowHeight;
- UWORD SizeType;
- Object *SizeImage;
-
- if(Screen -> Flags & SCREENHIRES)
- {
- SizeWidth = 18;
- SizeHeight = 10;
-
- SizeType = SYSISIZE_MEDRES;
- }
- else
- {
- SizeWidth = 13;
- SizeHeight = 11;
-
- SizeType = SYSISIZE_LOWRES;
- }
-
- SizeImage = NewObject(NULL, SYSICLASS,
- SYSIA_Size, SizeType,
- SYSIA_Which, SIZEIMAGE,
- SYSIA_DrawInfo, (ULONG)DrawInfo,
- TAG_DONE);
- if(SizeImage)
- {
- GetAttr(IA_Width, SizeImage,&SizeWidth);
- GetAttr(IA_Height, SizeImage,&SizeHeight);
-
- DisposeObject(SizeImage);
- }
-
- xdev -> image[UP_IMAGE] = (struct Image *)NewObject(NULL, SYSICLASS,
- SYSIA_Size, SizeType,
- SYSIA_Which, UPIMAGE,
- SYSIA_DrawInfo, (ULONG)DrawInfo,
- TAG_DONE);
- if(xdev -> image[UP_IMAGE])
- {
- GetAttr(IA_Height,xdev -> image[UP_IMAGE],&ArrowHeight);
-
- xdev -> image[DOWN_IMAGE] = (struct Image *)NewObject(NULL, SYSICLASS,
- SYSIA_Size, SizeType,
- SYSIA_Which, DOWNIMAGE,
- SYSIA_DrawInfo, (ULONG)DrawInfo,
- TAG_DONE);
- if(xdev -> image[DOWN_IMAGE])
- {
- xdev -> image[LEFT_IMAGE] = (struct Image *)NewObject(NULL, SYSICLASS,
- SYSIA_Size, SizeType,
- SYSIA_Which, LEFTIMAGE,
- SYSIA_DrawInfo, (ULONG)DrawInfo,
- TAG_DONE);
- if(xdev -> image[LEFT_IMAGE])
- {
- GetAttr(IA_Width,xdev -> image[LEFT_IMAGE],&ArrowWidth);
-
- xdev -> image[RIGHT_IMAGE] = (struct Image *)NewObject(NULL, SYSICLASS,
- SYSIA_Size, SizeType,
- SYSIA_Which, RIGHTIMAGE,
- SYSIA_DrawInfo, (ULONG)DrawInfo,
- TAG_DONE);
- if(xdev -> image[RIGHT_IMAGE])
- {
- xdev -> gadget[VERTICAL_SCROLLER] = NewObject(NULL, PROPGCLASS,
- GA_ID, VERTICAL_SCROLLER,
-
- GA_Top, Screen -> WBorTop + Screen -> Font -> ta_YSize + 2,
- GA_RelHeight, -(Screen -> WBorTop + Screen -> Font -> ta_YSize + 2 + SizeHeight + 1 + 2 * ArrowHeight),
- GA_Width, SizeWidth - 8,
- GA_RelRight, -(SizeWidth - 5),
-
- GA_GZZGadget, TRUE,
- GA_Immediate, TRUE,
- GA_FollowMouse, TRUE,
- GA_RelVerify, TRUE,
- GA_RightBorder, TRUE,
-
- PGA_Freedom, FREEVERT,
- PGA_NewLook, TRUE,
- PGA_Borderless, TRUE,
-
- PGA_Visible, 1,
- PGA_Total, 1,
- TAG_DONE);
- if(xdev -> gadget[VERTICAL_SCROLLER])
- {
- xdev -> gadget[HORIZONTAL_SCROLLER] = NewObject(NULL, PROPGCLASS,
- GA_ID, HORIZONTAL_SCROLLER,
- GA_Previous, (ULONG)(xdev -> gadget[VERTICAL_SCROLLER]),
-
- GA_Height, SizeHeight - 4,
- GA_RelBottom, -(SizeHeight - 4 + 1),
- GA_Left, 4,
- GA_RelWidth, -(2 + SizeWidth + 4 + 2 * ArrowWidth),
-
- GA_GZZGadget, TRUE,
- GA_Immediate, TRUE,
- GA_FollowMouse, TRUE,
- GA_RelVerify, TRUE,
- GA_BottomBorder,TRUE,
-
- PGA_Freedom, FREEHORIZ,
- PGA_NewLook, TRUE,
- PGA_Borderless, TRUE,
-
- PGA_Visible, 1,
- PGA_Total, 1,
- TAG_DONE);
- if(xdev -> gadget[HORIZONTAL_SCROLLER])
- {
- STATIC struct TagItem ArrowMappings[] =
- {
- { GA_ID, GA_ID, },
- { TAG_END, },
- };
-
- xdev -> gadget[UP_ARROW] = NewObject(NULL, BUTTONGCLASS,
- GA_ID, UP_ARROW,
- GA_Previous, (ULONG)(xdev -> gadget[HORIZONTAL_SCROLLER]),
-
- GA_GZZGadget, TRUE,
- GA_Image, (ULONG)(xdev -> image[UP_IMAGE]),
- GA_RelRight, -(SizeWidth - 1),
- GA_RelBottom, -(SizeHeight - 1 + 2 * ArrowHeight),
- GA_Height, ArrowHeight,
- GA_Width, SizeWidth,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_RightBorder, TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, (ULONG)ArrowMappings,
- TAG_DONE);
- if(xdev -> gadget[UP_ARROW])
- {
- xdev -> gadget[DOWN_ARROW] = NewObject(NULL, BUTTONGCLASS,
- GA_ID, DOWN_ARROW,
- GA_Previous, (ULONG)(xdev -> gadget[UP_ARROW]),
-
- GA_GZZGadget, TRUE,
- GA_Image, (ULONG)(xdev -> image[DOWN_IMAGE]),
- GA_RelRight, -(SizeWidth - 1),
- GA_RelBottom, -(SizeHeight - 1 + ArrowHeight),
- GA_Height, ArrowHeight,
- GA_Width, SizeWidth,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_RightBorder, TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, (ULONG)ArrowMappings,
- TAG_DONE);
- if(xdev -> gadget[DOWN_ARROW])
- {
- xdev -> gadget[LEFT_ARROW] = NewObject(NULL, BUTTONGCLASS,
- GA_ID, LEFT_ARROW,
- GA_Previous, (ULONG)(xdev -> gadget[DOWN_ARROW]),
-
- GA_GZZGadget, TRUE,
- GA_Image, (ULONG)(xdev -> image[LEFT_IMAGE]),
- GA_RelRight, -(SizeWidth - 1 + 2 * ArrowWidth),
- GA_RelBottom, -(SizeHeight - 1),
- GA_Height, SizeHeight,
- GA_Width, ArrowWidth,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_BottomBorder,TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, (ULONG)ArrowMappings,
- TAG_DONE);
- if(xdev -> gadget[LEFT_ARROW])
- {
- xdev -> gadget[RIGHT_ARROW] = NewObject(NULL, BUTTONGCLASS,
- GA_ID, RIGHT_ARROW,
- GA_Previous, (ULONG)(xdev -> gadget[LEFT_ARROW]),
-
- GA_GZZGadget, TRUE,
- GA_Image, (ULONG)(xdev -> image[RIGHT_IMAGE]),
- GA_RelRight, -(SizeWidth - 1 + ArrowWidth),
- GA_RelBottom, -(SizeHeight - 1),
- GA_Height, SizeHeight,
- GA_Width, ArrowWidth,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_BottomBorder,TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, (ULONG)ArrowMappings,
- TAG_DONE);
- if(xdev -> gadget[RIGHT_ARROW])
- Result = TRUE;
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- FreeScreenDrawInfo(Screen,DrawInfo);
- }
- }
- }
-
- return(Result);
- }
-
- /* WindowResize(gx_device *dev):
- *
- * Update the slider sizes and positions after the window
- * was resized.
- */
-
- private VOID
- WindowResize(gx_device *dev)
- {
- LONG DeltaX,
- DeltaY,
- Temp;
-
- /* Query the current horizontal slider position. */
-
- if((Temp = LAYERXOFFSET(xdev -> window) + xdev -> window -> GZZWidth) > xdev -> width)
- DeltaX = xdev -> width - Temp;
- else
- DeltaX = 0;
-
- /* Query the current vertical slider position. */
-
- if((Temp = LAYERYOFFSET(xdev -> window) + xdev -> window -> GZZHeight) > xdev -> height)
- DeltaY = xdev -> height - Temp;
- else
- DeltaY = 0;
-
- /* Move the currently displayed window area around. */
-
- if(DeltaX || DeltaY)
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,DeltaX,DeltaY);
-
- /* Update the new horizontal slider position and size. */
-
- SetGadgetAttrs(xdev -> gadget[HORIZONTAL_SCROLLER],xdev -> window,NULL,
- PGA_Top, LAYERXOFFSET(xdev -> window),
- PGA_Visible, xdev -> window -> GZZWidth,
- PGA_Total, xdev -> width,
- TAG_DONE);
-
- /* Update the new vertical slider position and size. */
-
- SetGadgetAttrs(xdev -> gadget[VERTICAL_SCROLLER],xdev -> window,NULL,
- PGA_Top, LAYERYOFFSET(xdev -> window),
- PGA_Visible, xdev -> window -> GZZHeight,
- PGA_Total, xdev -> height,
- TAG_DONE);
- }
-
- /* WindowUpdate(struct Gadget *Gadget,gx_device *dev):
- *
- * Move the currently visible portion of the
- * window according to the current slider
- * position.
- */
-
- private VOID
- WindowUpdate(struct Gadget *Gadget,gx_device *dev)
- {
- LONG Storage;
-
- switch(Gadget -> GadgetID)
- {
- case HORIZONTAL_SCROLLER:
-
- if(GetAttr(PGA_Top,Gadget,&Storage))
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,Storage - LAYERXOFFSET(xdev -> window),0);
-
- break;
-
- case VERTICAL_SCROLLER:
-
- if(GetAttr(PGA_Top,Gadget,&Storage))
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,0,Storage - LAYERYOFFSET(xdev -> window));
-
- break;
- }
- }
-
- /* MoveAround(struct Gadget *Gadget,int How,gx_device *dev):
- *
- * Move the currently visible window area according to
- * user input.
- */
-
- private VOID
- MoveAround(struct Gadget *Gadget,LONG How,gx_device *dev)
- {
- LONG Storage;
-
- if(GetAttr(PGA_Top,Gadget,&Storage))
- {
- LONG Max = 0;
-
- switch(Gadget -> GadgetID)
- {
- case HORIZONTAL_SCROLLER:
-
- Max = xdev -> width - xdev -> window -> GZZWidth;
- break;
-
- case VERTICAL_SCROLLER:
-
- Max = xdev -> height - xdev -> window -> GZZHeight;
- break;
- }
-
- switch(How)
- {
- case MOVE_MIN:
-
- Storage = 0;
- break;
-
- case MOVE_MAX:
-
- Storage = Max;
- break;
-
- case MOVE_DOWN:
-
- if(Storage > xdev -> height / 100)
- Storage -= xdev -> height / 100;
- else
- Storage = 0;
-
- break;
-
- case MOVE_FAR_DOWN:
-
- if(Storage > xdev -> height / 10)
- Storage -= xdev -> height / 10;
- else
- Storage = 0;
-
- break;
-
- case MOVE_FAR_UP:
-
- if(Storage + xdev -> width / 10 < Max)
- Storage += xdev -> width / 10;
- else
- Storage = Max;
-
- break;
-
- case MOVE_UP:
-
- if(Storage + xdev -> width / 100 < Max)
- Storage += xdev -> width / 100;
- else
- Storage = Max;
-
- break;
- }
-
- switch(Gadget -> GadgetID)
- {
- case HORIZONTAL_SCROLLER:
-
- if(LAYERXOFFSET(xdev -> window) != Storage)
- {
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,Storage - LAYERXOFFSET(xdev -> window),0);
-
- SetGadgetAttrs(Gadget,xdev -> window,NULL,
- PGA_Top,Storage,
- TAG_DONE);
- }
-
- break;
-
- case VERTICAL_SCROLLER:
-
- if(LAYERYOFFSET(xdev -> window) != Storage)
- {
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,0,Storage - LAYERYOFFSET(xdev -> window));
-
- SetGadgetAttrs(Gadget,xdev -> window,NULL,
- PGA_Top,Storage,
- TAG_DONE);
- }
-
- break;
- }
- }
- }
-
- /* DispatchSuperWindow(gx_device *dev):
- *
- * Dispatch user window input.
- */
-
- private VOID
- DispatchSuperWindow(gx_device *dev)
- {
- STATIC struct Gadget *CurrentGadget = NULL;
-
- struct IntuiMessage *IntuiMessage;
- ULONG MsgClass,
- MsgCode,
- MsgQualifier;
- struct Gadget *MsgGadget;
-
- while(NULL != (IntuiMessage = (struct IntuiMessage *)GetMsg(
- xdev -> window -> UserPort)))
- {
- MsgClass = IntuiMessage -> Class;
- MsgCode = IntuiMessage -> Code;
- MsgQualifier = IntuiMessage -> Qualifier;
- MsgGadget = IntuiMessage -> IAddress;
-
- ReplyMsg((struct Message *)IntuiMessage);
-
- switch(MsgClass)
- {
- case IDCMP_VANILLAKEY:
-
- if(MsgCode == '\033' || MsgCode == '\003')
- Signal((struct Task *)xdev -> main,SIG_KILL);
-
- break;
-
- case IDCMP_RAWKEY:
-
- switch(MsgCode)
- {
- case HELP_CODE:
-
- DisplayBeep(xdev -> window -> WScreen);
-
- break;
-
- case CURSORUP:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_MIN,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_FAR_DOWN,dev);
- else
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_DOWN,dev);
- }
-
- break;
-
- case CURSORLEFT:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_MIN,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_FAR_DOWN,dev);
- else
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_DOWN,dev);
- }
-
- break;
-
- case CURSORRIGHT:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_MAX,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_FAR_UP,dev);
- else
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_UP,dev);
- }
-
- break;
-
- case CURSORDOWN:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_MAX,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_FAR_UP,dev);
- else
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_UP,dev);
- }
-
- break;
-
- default:
-
- break;
- }
-
- break;
-
- case IDCMP_CLOSEWINDOW:
-
- Signal((struct Task *)xdev -> main,SIG_KILL);
-
- break;
-
- case IDCMP_GADGETDOWN:
-
- CurrentGadget = MsgGadget;
-
- WindowUpdate(MsgGadget,dev);
-
- break;
-
- case IDCMP_GADGETUP:
-
- CurrentGadget = NULL;
-
- WindowUpdate(MsgGadget,dev);
-
- break;
-
- case IDCMP_MOUSEMOVE:
-
- if(CurrentGadget)
- WindowUpdate(CurrentGadget,dev);
-
- break;
-
- case IDCMP_IDCMPUPDATE:
-
- switch(GetTagData(GA_ID,0,(struct TagItem *)MsgGadget))
- {
- case UP_ARROW:
-
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_DOWN,dev);
- break;
-
- case DOWN_ARROW:
-
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_UP,dev);
- break;
-
- case LEFT_ARROW:
-
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_DOWN,dev);
- break;
-
- case RIGHT_ARROW:
-
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_UP,dev);
- break;
-
- default:
-
- break;
- }
-
- break;
-
- case IDCMP_NEWSIZE:
-
- WindowResize(dev);
-
- break;
-
- default:
-
- break;
- }
- }
- }
-
- /* PrintPrinterError(const char *header, LONG io_Error):
- *
- * Print a real error message for Printer.device errors.
- */
-
- private VOID
- PrintPrinterError(const char *header, LONG io_Error)
- {
- char buffer[256];
- char defaultmessage[64];
- const char *errormessage;
-
- switch (io_Error)
- {
- case PDERR_CANCEL:
- errormessage = "user cancelled print";
- break;
- case PDERR_NOTGRAPHICS:
- errormessage = "printer cannot output graphics";
- break;
- case PDERR_BADDIMENSION:
- errormessage = "print dimensions illegal";
- break;
- case PDERR_INTERNALMEMORY:
- errormessage = "no memory for internal variables";
- break;
- case PDERR_BUFFERMEMORY:
- errormessage = "no memory for print buffer";
- break;
- case IOERR_OPENFAIL:
- errormessage = "device/unit failed to open";
- break;
- case IOERR_ABORTED:
- errormessage = "request terminated early [after AbortIO()]";
- break;
- case IOERR_NOCMD:
- errormessage = "command not supported by device";
- break;
- case IOERR_BADLENGTH:
- errormessage = "not a valid length (usually IO_LENGTH)";
- break;
- case IOERR_BADADDRESS:
- errormessage = "invalid address (misaligned or bad range)";
- break;
- case IOERR_UNITBUSY:
- errormessage = "device opens ok, but requested unit is busy";
- break;
- case IOERR_SELFTEST:
- errormessage = "hardware failed self-test";
- break;
- default:
- sprintf(defaultmessage, "unknown I/O error #%ld", io_Error);
- errormessage = defaultmessage;
- break;
- }
- sprintf(buffer, "%s (%s)\n", header, errormessage);
- eprintf(buffer);
- }
-
- /* Simple routine to call the cleanup routine of a device,
- * all devices are smart enough to handle shutdown in
- * case they have not been opened yet.
- */
-
- private void
- close_device(gx_device_amiga *dev)
- {
- // if(xdev -> std_procs . close_device)
- // (*xdev -> std_procs . close_device)((gx_device *)dev);
- if( dev_proc( xdev, close_device ) )
- (*(dev_proc( xdev, close_device )))((gx_device *)dev );
- }
-
- /* devcleanup():
- *
- * Clean up all devices, free all resources.
- */
-
- void
- devcleanup()
- {
- close_device(&gs_amiga_device);
- close_device(&gs_amiga_custom_device);
- close_device(&gs_amiga_printer_device);
- close_device(&gs_amiga_ilbm_device);
- }
-
- /* amiga_set_pen(gx_device *dev,gx_color_index color):
- *
- * Sets the rendering pen and remembers the current
- * settings.
- */
-
- private VOID
- amiga_set_pen(gx_device *dev,gx_color_index color)
- {
- if(xdev -> last_pen != color)
- SetAPen(xdev -> rport,xdev -> last_pen = color);
- }
-
- /* amiga_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue):
- *
- * Map a colour either to the black or the light rendering pen.
- */
-
- private gx_color_index
- amiga_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue)
- {
- if((red | green | blue) > gx_max_color_value / 2)
- return(LightPen);
- else
- return(DarkPen);
- }
-
- /* amiga_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3]):
- *
- * Map the light/dark rendering pen to RGB values.
- */
-
- private int
- amiga_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3])
- {
- int i;
-
- if(color == LightPen)
- {
- for(i = 0 ; i < 3 ; i++)
- rgb[i] = gx_max_color_value;
- }
- else
- {
- for(i = 0 ; i < 3 ; i++)
- rgb[i] = 0;
- }
-
- return(0);
- }
-
- /* AllocatePens(struct ViewPort *VPort,LONG CubeSize):
- *
- * Allocate shareable viewport pens.
- */
-
- private LONG *
- AllocatePens(struct ViewPort *VPort,LONG CubeSize)
- {
- if(GfxBase -> LibNode . lib_Version >= 39)
- {
- LONG Total = CubeSize * CubeSize * CubeSize,*Pens;
-
- Pens = (LONG *)AllocVec(sizeof(LONG) * Total, MEMF_ANY);
- if(Pens)
- {
- LONG i,r,g,b,max = CubeSize - 1;
-
- for(i = 0 ; i < Total ; i++)
- Pens[i] = -1;
-
- i = 0;
-
- for(r = 0 ; r < CubeSize ; r++)
- {
- for(g = 0 ; g < CubeSize ; g++)
- {
- for(b = 0 ; b < CubeSize ; b++)
- {
- if((Pens[i++] = ObtainBestPen(VPort -> ColorMap,SPREAD((255 * r) / max),SPREAD((255 * g) / max),SPREAD((255 * b) / max),
- OBP_FailIfBad, TRUE,
- OBP_Precision, PRECISION_IMAGE,
- TAG_DONE)) == -1)
- {
- FreeVec(Pens);
-
- return(NULL);
- }
- }
- }
- }
-
- return(Pens);
- }
- }
-
- return(NULL);
- }
-
- /* amiga_open_default(gx_device *dev):
- *
- * Open the default device, i.e. a window on the Workbench screen.
- */
-
- private int
- amiga_open_default(gx_device *dev)
- {
- struct Screen *DefaultScreen;
-
- /* Get a lock on the default public screen. */
-
- DefaultScreen = LockPubScreen(NULL);
- if(DefaultScreen)
- {
- struct DisplayInfo DisplayInfo;
- ULONG Mode;
-
- /* Get the default public screen display mode. */
-
- Mode = GetVPModeID(&DefaultScreen -> ViewPort);
-
- /* Inquire display mode information. */
-
- if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,Mode))
- {
- LONG ScreenWidth,
- ScreenHeight;
- LONG i;
- LONG Depth;
-
- if(GfxBase -> LibNode . lib_Version >= 39)
- Depth = GetBitMapAttr(DefaultScreen -> RastPort . BitMap,BMA_DEPTH);
- else
- Depth = DefaultScreen -> RastPort . BitMap -> Depth;
-
- /* Determine screen view dimensions. */
-
- if(DefaultScreen -> ViewPort . ColorMap -> cm_vpe)
- {
- struct ViewPortExtra *Extra = DefaultScreen -> ViewPort . ColorMap -> cm_vpe;
-
- ScreenWidth = Extra -> DisplayClip . MaxX - Extra -> DisplayClip . MinX + 1;
- ScreenHeight = Extra -> DisplayClip . MaxY - Extra -> DisplayClip . MinY + 1;
- }
- else
- {
- struct ViewPortExtra *Extra;
-
- Extra = (struct ViewPortExtra *)GfxLookUp(
- &DefaultScreen -> ViewPort);
- if(Extra)
- {
- ScreenWidth = Extra -> DisplayClip . MaxX - Extra -> DisplayClip . MinX + 1;
- ScreenHeight = Extra -> DisplayClip . MaxY - Extra -> DisplayClip . MinY + 1;
- }
- else
- {
- ScreenWidth = DefaultScreen -> Width;
- ScreenHeight = DefaultScreen -> Height;
- }
- }
-
- /* Adjust device to screen resolution. */
-
- if (!ResolutionSwitch) /* Has user set -r at command line? */
- { /* no */
-
- /* Compute the dots_per_inch resolution from the
- * ticks_per_pixel resolution in the display database.
- * See #define MAGIC_... for a comment.
- */
-
- if (DisplayInfo.Resolution.x && DisplayInfo.Resolution.y)
- {
- dev->x_pixels_per_inch = MAGIC_DPI_BASE_VALUE
- / DisplayInfo.Resolution.x;
- dev->y_pixels_per_inch = MAGIC_DPI_BASE_VALUE
- / DisplayInfo.Resolution.y;
-
- if (GeometrySwitch) /* Has user set -g at command line? */
- { /* yes => update MediaSize to remain consistent */
- gx_device_set_width_height(dev, dev->width,
- dev->height);
- }
- else
- { /* no => update width/height to remain consistent */
- gx_device_set_media_size(dev, dev->MediaSize[0],
- dev->MediaSize[1]);
- }
- }
- }
-
- /* Allocate a bitmap ready to be used for
- * rendering.
- */
-
- xdev -> super_bitmap = CreateBitMap(xdev -> width,
- xdev -> height, Depth, BMF_DISPLAYABLE,
- DefaultScreen -> RastPort . BitMap, FALSE);
- if(xdev -> super_bitmap)
- {
- /* Clear the bitplanes. */
-
- BltBitMap(xdev -> super_bitmap,0,0,xdev -> super_bitmap,0,0,xdev -> width,xdev -> height,0x00,(1 << xdev -> super_bitmap -> Depth) - 1,NULL);
-
- /* Create the scroller handles. */
-
- if(CreateScrollers(dev,DefaultScreen))
- {
- struct IBox ZoomBox;
-
- /* Set up the window alternate
- * position.
- */
-
- ZoomBox . Left = 0;
- ZoomBox . Top = DefaultScreen -> BarHeight + 1;
- ZoomBox . Width = ScreenWidth;
- ZoomBox . Height = ScreenHeight - ZoomBox . Top;
-
- /* Eventually, open the display window. */
-
- xdev -> window = OpenWindowTags(NULL,
- WA_InnerWidth, MIN(DefaultScreen->Width / 2,
- xdev -> width),
- WA_InnerHeight, MIN(DefaultScreen->Height / 2,
- xdev -> height),
- WA_CloseGadget, TRUE,
- WA_DepthGadget, TRUE,
- WA_SizeGadget, TRUE,
- WA_SizeBRight, TRUE,
- WA_SizeBBottom, TRUE,
- WA_Zoom, (ULONG)(&ZoomBox),
- WA_DragBar, TRUE,
- WA_NoCareRefresh, TRUE,
- WA_GimmeZeroZero, TRUE,
- WA_RMBTrap, TRUE,
- WA_SuperBitMap, (ULONG)(xdev->super_bitmap),
- WA_Gadgets, (ULONG)(xdev->gadget[VERTICAL_SCROLLER]),
- WA_CustomScreen, (ULONG)DefaultScreen,
- WA_Title, (ULONG)"Ghostscript Amiga output window",
- TAG_DONE);
- if(xdev -> window)
- {
- xdev -> temp_rport = CreateTempRPort(
- xdev -> window -> RPort);
- if(xdev -> temp_rport)
- {
- xdev -> temp_array = (UBYTE *)AllocVec(
- (xdev -> window -> WScreen -> Width + 15) & ~15,
- MEMF_ANY);
- if(xdev -> temp_array)
- {
- const sigset_t trapped = sigmask(SIGINT);
- struct Task *Task;
- long TaskPri;
- #ifdef __PPC__
- struct TagItem cttags[] = { { TASKATTR_CODE, DispatchTask },
- { TASKATTR_NAME, "Ghostscript window dispatcher" },
- { TASKATTR_PRI, 0 },
- { TASKATTR_STACKSIZE, 20000 },
- { TASKATTR_INHERITR2, 1 },
- { TAG_DONE, 0 }
- };
- #endif
-
- /* Don't let anybody interrupt us! */
- #ifdef IXEMUL
- sigprocmask(SIG_BLOCK,&trapped,NULL);
- #endif
- /* Who's calling? */
-
- xdev -> main = (struct Process *)FindTask(NULL);
-
- /* Bring the window dispatcher task
- * to life with +1 priority...
- */
-
- Forbid();
-
- TaskPri = 1 +
- xdev->main->pr_Task.tc_Node.ln_Pri;
- if (127 < TaskPri) /* Ouch... */
- TaskPri = 127; /* ;-) */
-
- #ifdef __PPC__
- DispatchTaskDevice = dev;
- cttags[ 2 ].ti_Data = TaskPri;
- SetSignal(0,SIG_HANDSHAKE);
- Task = CreateTaskPPC( cttags );
- if(Task)
- {
- Wait(SIG_HANDSHAKE);
- Task = xdev -> dispatcher;
- }
- #else
- Task = CreateTask(
- "Ghostscript window dispatcher",
- TaskPri, DispatchTask, 8192);
-
- Forbid();
-
- if(Task)
- {
- /* Cheap... */
-
- Task -> tc_UserData = dev;
-
- /* Clear the handshake bit. */
-
- SetSignal(0,SIG_HANDSHAKE);
-
- /* Wake it up. */
-
- Signal(Task,SIG_HANDSHAKE);
-
- /* Wake the task up. */
-
- Signal(Task,SIG_WAKEUP);
-
- /* Wait for the report. */
-
- Wait(SIG_HANDSHAKE);
-
- /* Get the result. */
-
- Task = xdev -> dispatcher;
- }
-
- Permit();
- #endif
-
- /* Unblock signals. */
- #ifdef IXEMUL
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- #endif
- /* Did we succeed in creating
- * the dispatcher task?
- */
-
- if(Task)
- {
- UWORD MaxValue = 0,
- MinValue = 15000,
- Value,
- R,G,B;
-
- /* Set the window limits. */
-
- WindowLimits(xdev -> window,xdev -> window -> BorderLeft + MINIMUM_WIDTH + xdev -> window -> BorderRight,xdev -> window -> BorderTop + MINIMUM_HEIGHT + xdev -> window -> BorderBottom,xdev -> window -> BorderLeft + xdev -> width + xdev -> window -> BorderRight,xdev -> window -> BorderTop + xdev -> height + xdev -> window -> BorderBottom);
-
- /* Update the sliders. */
-
- WindowResize(dev);
-
- /* Look for the darkest and the lightest screen colours. */
-
- for(i = 0 ; i < MIN(xdev -> window -> WScreen -> ViewPort . ColorMap -> Count,(1 << Depth)) ; i++)
- {
- Value = GetRGB4(xdev -> window -> WScreen -> ViewPort . ColorMap,i);
-
- R = (Value >> 8) & 0xF;
- G = (Value >> 4) & 0xF;
- B = Value & 0xF;
-
- /* Luminance conversion included */
-
- Value = R * 299 + G * 588 + B * 113;
-
- if(Value > MaxValue)
- {
- MaxValue = Value;
-
- LightPen = i;
- }
-
- if(Value < MinValue)
- {
- MinValue = Value;
-
- DarkPen = i;
- }
- }
-
- /* Fill in the rest. */
-
- xdev -> rport = xdev -> window -> RPort;
-
- /* Does the display support
- * at least eight colours?
- */
-
- if(Depth >= 3)
- {
- LONG cube_size,max;
-
- /* Set up a fitting colour cube. */
-
- for(cube_size = 6 ; cube_size >= 2 ; cube_size--)
- {
- if((max = cube_size * cube_size * cube_size) <= 1 << Depth)
- break;
- }
-
- /* Got enough colours? */
-
- if(cube_size != 1)
- {
- LONG *Pens;
-
- /* Try to grab the cube colours,
- * making a colour display.
- */
-
- Pens = AllocatePens(&xdev -> window -> WScreen -> ViewPort,cube_size);
- if(Pens)
- set_colour_device((gx_device_amiga *)dev,cube_size,Pens);
- }
- }
-
- SetBPen(xdev -> rport,0);
- SetDrMd(xdev -> rport,JAM2);
-
- amiga_set_pen(dev,DarkPen);
-
- UnlockPubScreen(NULL,DefaultScreen);
-
- return(0);
- }
- else
- eprintf("Ghostscript: failed to create dispatcher task\n");
- }
- else
- eprintf("Ghostscript: failed to create temporary line buffer\n");
- }
- else
- eprintf("Ghostscript: failed to create temporary raster port\n");
- }
- else
- eprintf("Ghostscript: failed to open window\n");
- }
- else
- eprintf("Ghostscript: failed to allocate scrollers\n");
- }
- else
- eprintf("Ghostscript: failed to allocate bitmap\n");
- }
- else
- eprintf("Ghostscript: failed to get display mode information\n");
-
- UnlockPubScreen(NULL,DefaultScreen);
- }
- else
- eprintf("Ghostscript: failed to lock default public screen\n");
-
- return_error(gs_error_unknownerror);
- }
-
- private int
- amiga_open_custom(gx_device *dev)
- {
- UBYTE Buffer[DISPLAYNAMELEN + 1] = ""; /* see graphics/displayinfo.h */
- ULONG ScreenID = INVALID_ID;
- BOOL DontTouch = FALSE;
-
- /* Has user supplied the ID of a Display Mode? */
-
- if (1 == sscanf(xdev->display_mode, "0x%lx", &ScreenID)
- || 1 == sscanf(xdev->display_mode, "0X%lx", &ScreenID))
- { /* yes => check wether it is available */
-
- if (ModeNotAvailable(ScreenID))
- {
- ScreenID = INVALID_ID;
- }
- else
- {
- DontTouch = TRUE; /* Don't overwrite the env. variable. */
- }
- }
- else
- { /* no */
-
- /* Has user supplied the name of a Display Mode? */
-
- if ('\0' != xdev->display_mode[0])
- { /* yes */
-
- strcpy(Buffer, xdev->display_mode);
- }
- else
- { /* no => try to read it from the environment variable */
-
- GetVar("GS_DISPLAYMODE", Buffer, sizeof (Buffer), NULL);
- }
-
- if ('\0' != Buffer[0])
- {
- UBYTE PatternBuffer[(sizeof (Buffer) * 2) + 2];
-
- /* Set up the search pattern. */
-
- if (0 <= ParsePatternNoCase(Buffer, PatternBuffer,
- sizeof (PatternBuffer)))
- {
- ULONG CurrentID = INVALID_ID;
-
- /* Scan the entire list. */
-
- while (INVALID_ID != (CurrentID = NextDisplayInfo(CurrentID)))
- {
- struct NameInfo NameInfo;
-
- /* Is this mode available? */
-
- if (ModeNotAvailable(CurrentID))
- { /* no => continue loop */
- continue;
- }
-
- /* Get the name information. */
-
- if (GetDisplayInfoData(NULL, (UBYTE *)&NameInfo,
- sizeof (struct NameInfo), DTAG_NAME, CurrentID))
- {
- /* Does the mode name match the pattern given? */
- if (MatchPatternNoCase(PatternBuffer, NameInfo.Name))
- {
- ScreenID = CurrentID;
-
- /* Don't overwrite the env. variable. */
-
- DontTouch = TRUE;
- break;
- }
- }
- }
- }
- }
- }
-
- if (INVALID_ID == ScreenID && AslBase)
- {
- struct ScreenModeRequester *ScreenModeRequester;
-
- ScreenModeRequester = (struct ScreenModeRequester *)
- AllocAslRequestTags(ASL_ScreenModeRequest, TAG_DONE);
- if (ScreenModeRequester)
- {
- if (AslRequestTags(ScreenModeRequester,
- ASLSM_TitleText, (ULONG)"Select Ghostscript Display Mode",
- ASLSM_MinDepth, 1,
- ASLSM_MaxDepth, 8,
- TAG_DONE))
- {
- ScreenID = ScreenModeRequester->sm_DisplayID;
- FreeAslRequest(ScreenModeRequester);
- }
- else
- {
- /* Check wether any error occured (V38 only) */
-
- if (38 <= AslBase->lib_Version)
- {
- if (0 != IoErr())
- { /* yes => print additional error message */
- eprintf("Ghostscript: failed to display screenmode "
- "requester\n");
- }
- }
-
- /* User cancelled or IoErr() => fall back to default */
-
- FreeAslRequest(ScreenModeRequester);
- return (amiga_open_default(dev));
- }
- }
- }
-
- /* Is selected mode available? */
-
- if (ModeNotAvailable(ScreenID))
- { /* no => fall back to default */
- return (amiga_open_default(dev));
- }
- else
- { /* yes => try to open the screen */
- int result = amiga_open(dev, ScreenID);
-
- /* If successful store the name of the
- * screen mode selected.
- */
-
- if(!result && !DontTouch)
- {
- struct NameInfo NameInfo;
-
- if (GetDisplayInfoData(NULL, (UBYTE *)&NameInfo,
- sizeof (struct NameInfo), DTAG_NAME, ScreenID))
- {
- SetVar("GS_DISPLAYMODE", NameInfo.Name, -1, NULL);
- }
- }
-
- return (result);
- }
- }
-
- /* amiga_open_printer(gx_device *dev):
- *
- * Open the printer device.
- */
-
- private int
- amiga_open_printer(gx_device *dev)
- {
- xdev->port = CreateMsgPort();
- if (xdev->port)
- {
- xdev->printer = (struct IODRPReq *)CreateIORequest(xdev->port,
- sizeof(struct IODRPReq));
- if (xdev->printer)
- {
- if (!OpenDevice("printer.device", 0,
- (struct IORequest *)xdev->printer, 0))
- {
- struct PrinterData *PD;
- struct PrinterExtendedData *PED;
- struct Preferences *Prefs;
-
- /* Get the printer internal data. */
-
- PD = (struct PrinterData *)xdev->printer->io_Device;
- PED = &PD->pd_SegmentData->ps_PED;
- Prefs = &PD->pd_Preferences;
-
- /* Adjust device to current printer resolution. */
-
- if (!ResolutionSwitch) /* Has user set -r at command line? */
- { /* no */
- dev->x_pixels_per_inch = (float)PED->ped_XDotsInch;
- dev->y_pixels_per_inch = (float)PED->ped_YDotsInch;
-
- if (GeometrySwitch) /* Has user set -g at command line? */
- { /* yes => update MediaSize to remain consistent */
- gx_device_set_width_height(dev, dev->width,
- dev->height);
- }
- else
- { /* no => update width/height to remain consistent */
- gx_device_set_media_size(dev, dev->MediaSize[0],
- dev->MediaSize[1]);
- }
- }
-
- xdev->rport = (struct RastPort *)AllocVec(
- sizeof(struct RastPort), MEMF_ANY);
- if (xdev->rport)
- {
- const sigset_t trapped = sigmask(SIGINT);
- struct BitMap DummyBitMap;
- UWORD DummyLine[12];
-
- InitRastPort(xdev -> rport);
-
- /* Compensate for the non-printable are of the page:
- *
- * Unfortunately the standard Amiga printer drivers
- * are too poorly designed for that matter and do just
- * provide MaxXDots/MaxYDots, which is obviously not
- * enough to place the image correctly on the paper.
- * Therefore, a good approximation seems to be to
- * substract half of these values on either side of
- * the bitmap. Then a SPECIAL_NOPRINT dump is
- * performed to see what the actual printsize in
- * printerpixels would be. If this reveals, that the
- * user has set preferences to produce a smaller
- * image the margins will be ignored for the real dump.
- * (Of course, one could compute all this without the
- * NOPRINT dump, it's just more convenient this way
- * and blames the OS for all its buggy calculations ;-)
- *
- * In general this provides a policy which tries to do
- * a 1:1 dump prior to exact placement (which rules if
- * the real non-printable margins of the printer don't
- * fit to the estimated halves on either side).
- *
- * One should probably use the gs printer drivers
- * anyway if accuracy matters!
- */
-
- /* NOTE: Unfortunately the printer device corrects the aspect ratio based on
- * a ModeID instead of just the supplied dimensions when a dump without
- * SPECIAL_ASPECT is requested and ABSOLUTE_DIMENSIONS is set in preferences.
- * Therefore it seems best to supply a ModeID which fits to the default gs
- * device settings as well as to many printers (1:1); this may lead to wrong
- * but expectable results in case the device resolution has a different aspect
- * ratio.
- * TODO: Maybe the device settings could be 'normalized' to 1:1 to circumvent
- * this problem.
- */
-
- xdev->printer->io_Command = PRD_DUMPRPORT;
- xdev->printer->io_RastPort = xdev->rport;
- xdev->printer->io_Modes = VGAPRODUCT_KEY; /* 1:1 */
- xdev->printer->io_SrcX =
- MAX((LONG)(dev->width - PED->ped_MaxXDots), 0) / 2;
- xdev->printer->io_SrcY = PED->ped_MaxYDots ?
- MAX((LONG)(dev->height - PED->ped_MaxYDots), 0) / 2
- : 0;
- xdev->printer->io_SrcWidth =
- MIN(dev->width, PED->ped_MaxXDots);
- xdev->printer->io_SrcHeight = PED->ped_MaxYDots ?
- MIN(dev->height, PED->ped_MaxYDots) : dev->height;
- xdev->printer->io_DestCols = xdev->printer->io_SrcWidth;
- xdev->printer->io_DestRows = xdev->printer->io_SrcHeight;
- xdev->printer->io_Special = (SPECIAL_NOPRINT);
-
- /* Cook up a dummy bitmap to keep
- * `smart' drivers from complaining.
- */
-
- InitBitMap(&DummyBitMap, 12, dev->width, dev->height);
-
- DummyBitMap.Planes[0] = (PLANEPTR)&DummyLine;
-
- xdev->rport->BitMap = &DummyBitMap;
-
- /* Don't let them stop us now! */
- #ifdef IXEMUL
- sigprocmask(SIG_BLOCK,&trapped,NULL);
- #endif
- /* Ask for it... */
-
- if(!DoIO((struct IORequest *)xdev -> printer))
- {
- LONG Depth,
- NumColours,
- CubeSize;
-
- /* Unblock ^C signal. */
- #ifdef IXEMUL
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- #endif
- /* Provide everything to perform the real dump:
- *
- * Check wether preference settings leaded to
- * an image smaller than the largest possible one.
- * If this is the case the margins determined
- * above are ignored, as the image will most
- * likely fit within the printable area of the
- * page (except for those rare cases where a
- * printout is requested whith boundaries just
- * smaller than the largest possible ones by
- * values within the determined margins).
- */
-
- if (xdev->printer->io_DestCols
- < xdev->printer->io_SrcWidth)
- { /* reset dimensions to print the entire image */
- xdev->printer->io_SrcX = 0;
- xdev->printer->io_SrcWidth = xdev->width;
- }
- if (xdev->printer->io_DestRows
- < xdev->printer->io_SrcHeight)
- { /* reset dimensions to print the entire image */
- xdev->printer->io_SrcY = 0;
- xdev->printer->io_SrcHeight = xdev->height;
- }
- xdev->printer->io_DestCols =
- xdev->printer->io_SrcWidth;
- xdev->printer->io_DestRows =
- xdev->printer->io_SrcHeight;
- xdev->printer->io_Special &= ~(SPECIAL_NOPRINT);
-
- /* Set up the default colour values. */
-
- if(Prefs -> PrintShade == SHADE_BW)
- {
- Depth = 1;
- NumColours = 2;
- CubeSize = 0;
- }
- else
- {
- Depth = 12;
- NumColours = 4096;
- CubeSize = 16;
- }
-
- /* Try to allocate a suitable bitmap.
- * If an allocation fails, rescale the
- * colour cube and bitmap depth and
- * retry. Minimum are eight colours.
- */
-
- do
- {
- /* Try to allocate the raster... */
-
- xdev->bitmap = CreateBitMap(xdev->width,
- xdev->height, Depth, NULL, NULL, TRUE);
- if (!(xdev->bitmap))
- {
- /* Any chance to rescale the cube? */
-
- if(Depth < 2)
- break;
- else
- {
- /* One plane less... */
-
- Depth--;
-
- /* Rescale the cube. */
-
- while(CubeSize >= 2)
- {
- NumColours = CubeSize * CubeSize
- * CubeSize;
- if(NumColours <= (1 << Depth))
- break;
- else
- CubeSize--;
- }
-
- /* Less than eight colours? */
-
- if(CubeSize < 2)
- break;
- }
- }
- }
- while(!xdev -> bitmap);
-
- /* Got the bitmap? */
-
- if(xdev -> bitmap)
- {
- /* Allocate a suitable colour map. */
-
- xdev -> colormap = GetColorMap(NumColours);
- if(xdev -> colormap)
- {
- /* Black & white only? */
-
- if(NumColours == 2)
- {
- SetRGB4CM(xdev -> colormap,0,0x0,0x0,0x0);
- SetRGB4CM(xdev -> colormap,1,0xF,0xF,0xF);
- }
- else
- {
- LONG i = 0,r,g,b,max = CubeSize - 1;
-
- /* Fill in the colour cube. */
-
- for(r = 0 ; r < CubeSize ; r++)
- {
- for(g = 0 ; g < CubeSize ; g++)
- {
- for(b = 0 ; b < CubeSize ; b++)
- SetRGB4CM(xdev->colormap, i++,
- (15 * r) / max,
- (15 * g) / max,
- (15 * b) / max);
- }
- }
-
- set_colour_printer_device(
- (gx_device_amiga *)dev, CubeSize);
- }
-
- xdev->printer->io_ColorMap = xdev->colormap;
- xdev->rport->BitMap = xdev->bitmap;
-
- return(0);
- }
- else
- eprintf("Ghostscript: failed to allocate "
- "colour map\n");
- }
- else
- {
- char buffer[256];
-
- sprintf(buffer, "Ghostscript: failed to allocate "
- "raster (wanted %ld, largest %ld)\n",
- (dev->width + 15) / 8 * dev->height * Depth,
- AvailMem(MEMF_ANY | MEMF_LARGEST));
-
- eprintf(buffer);
- }
- }
- else
- {
- #ifdef IXEMUL
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- #endif
- PrintPrinterError("Ghostscript: failed to query "
- "printer page size ", xdev->printer->io_Error);
- }
- }
- else
- eprintf("Ghostscript: failed to allocate raster port\n");
- }
- else
- {
- PrintPrinterError("Ghostscript: printer.device ",
- xdev->printer->io_Error);
- }
- }
- else
- eprintf("Ghostscript: failed to allocate device driver\n");
- }
- else
- eprintf("Ghostscript: failed to create io port\n");
-
- return_error(gs_error_unknownerror);
- }
-
- /* amiga_output_page_printer(gx_device *dev,int,int):
- *
- * Send a bitmap to the printer.
- */
-
- private int
- amiga_output_page_printer(gx_device *dev,int num_copies,int flush)
- {
- const sigset_t trapped = sigmask(SIGINT);
- int result = gs_error_unknownerror, i;
- ULONG Signals;
-
- /* We cannot possibly allow being interrupted in the middle
- * of a raster dump!
- */
- #ifdef IXEMUL
- sigprocmask(SIG_BLOCK,&trapped,NULL);
- #endif
- for(i = 0 ; i < num_copies ; i++)
- {
- SetSignal(0,SIGBREAKF_CTRL_C | (1L << xdev -> port -> mp_SigBit));
-
- SendIO((struct IORequest *)xdev -> printer);
-
- Signals = Wait(SIGBREAKF_CTRL_C | (1L << xdev -> port -> mp_SigBit));
-
- if(Signals & SIGBREAKF_CTRL_C)
- {
- if(!CheckIO((struct IORequest *)xdev -> printer))
- AbortIO((struct IORequest *)xdev -> printer);
-
- WaitIO((struct IORequest *)xdev -> printer);
-
- eprintf("Ghostscript: printing aborted\n");
-
- result = gs_error_unknownerror;
-
- break;
- }
-
- if(Signals & (1L << xdev -> port -> mp_SigBit))
- {
- if(WaitIO((struct IORequest *)xdev -> printer))
- {
- result = gs_error_unknownerror;
-
- PrintPrinterError("Ghostscript: failed to print raster ",
- xdev->printer->io_Error);
-
- break;
- }
- else
- result = 0;
- }
- }
- #ifdef IXEMUL
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- #endif
-
- if (result)
- return_error(result);
- else
- return (0);
- }
-
- /* amiga_close_printer(gx_device *dev):
- *
- * Close the printer driver.
- */
-
- private int
- amiga_close_printer(gx_device *dev)
- {
- if(xdev -> bitmap)
- {
- DeleteBitMap(xdev -> bitmap,TRUE);
-
- xdev -> bitmap = NULL;
- }
-
- if(xdev -> rport)
- {
- FreeVec(xdev -> rport);
-
- xdev -> rport = NULL;
- }
-
- if(xdev -> colormap)
- {
- FreeColorMap(xdev -> colormap);
-
- xdev -> colormap = NULL;
- }
-
- if(xdev -> printer)
- {
- if(xdev -> printer -> io_Device)
- CloseDevice((struct IORequest *)xdev -> printer);
-
- DeleteIORequest(xdev -> printer);
-
- xdev -> printer = NULL;
- }
-
- if(xdev -> port)
- {
- DeleteMsgPort(xdev -> port);
-
- xdev -> port = NULL;
- }
-
- return(0);
- }
-
- /* amiga_get_bits(gx_device *dev,int y,byte *str,byte **actual_data):
- *
- * Read the raster bits into a buffer.
- */
-
- private int
- amiga_get_bits(gx_device *dev,int y,byte *str,byte **actual_data)
- {
- if(y < 0 || y > xdev -> height)
- return_error(gs_error_unknownerror);
- else
- {
- if(actual_data)
- *actual_data = (byte *)(xdev -> bitmap -> Planes[0] + xdev -> bitmap -> BytesPerRow * y);
- else
- memcpy(str,xdev -> bitmap -> Planes[0] + xdev -> bitmap -> BytesPerRow * y,xdev -> bitmap -> BytesPerRow);
-
- return(0);
- }
- }
-
- /* amiga_open(gx_device *dev,ULONG Mode):
- *
- * Open a custom screen.
- */
-
- private int
- amiga_open(gx_device *dev,ULONG Mode)
- {
- struct DisplayInfo DisplayInfo;
- struct DimensionInfo DimensionInfo;
-
- /* Get the display dimensions. */
-
- if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,Mode) && GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(struct DimensionInfo),DTAG_DIMS,Mode))
- {
- /* Two shades only, black & white */
-
- STATIC struct ColorSpec Colours[] =
- {
- { 0, 0x0000, 0x0000, 0x0000, },
- { 1, 0xFFFF, 0xFFFF, 0xFFFF, },
- { -1, },
- };
-
- LONG i,cube_size,max;
- LONG ScreenDepth;
-
- /* Start up with a maximum depth display. */
-
- ScreenDepth = DimensionInfo . MaxDepth;
-
- /* Check to see whether we will be able to
- * build a colour display or not.
- */
-
- for(cube_size = 6 ; cube_size >= 2 ; cube_size--)
- {
- if((max = cube_size * cube_size * cube_size) <= 1 << ScreenDepth)
- break;
- }
-
- /* Got enough colours? */
-
- if(cube_size != 1)
- set_colour_device((gx_device_amiga *)dev,cube_size,NULL);
- else
- {
- ScreenDepth = 1;
-
- set_mono_device((gx_device_amiga *)dev);
- }
-
- /* Adjust device to screen resolution. */
-
- if (!ResolutionSwitch) /* Has user set -r at command line? */
- { /* no */
-
- /* Compute the dots_per_inch resolution from the
- * ticks_per_pixel resolution in the display database.
- * See #define MAGIC_... for a comment.
- */
-
- if (DisplayInfo.Resolution.x && DisplayInfo.Resolution.y)
- {
- dev->x_pixels_per_inch = MAGIC_DPI_BASE_VALUE
- / DisplayInfo.Resolution.x;
- dev->y_pixels_per_inch = MAGIC_DPI_BASE_VALUE
- / DisplayInfo.Resolution.y;
-
- if (GeometrySwitch) /* Has user set -g at command line? */
- { /* yes => update MediaSize to remain consistent */
- gx_device_set_width_height(dev, dev->width,
- dev->height);
- }
- else
- { /* no => update width/height to remain consistent */
- gx_device_set_media_size(dev, dev->MediaSize[0],
- dev->MediaSize[1]);
- }
- }
- }
-
- /* Ensure the computed values will fit on the screen */
-
- if (dev->width < DimensionInfo.MinRasterWidth)
- gx_device_set_width_height(dev, DimensionInfo.MinRasterWidth,
- dev->height);
- if (dev->width > DimensionInfo.MaxRasterWidth)
- gx_device_set_width_height(dev, DimensionInfo.MaxRasterWidth,
- dev->height);
- if (dev->height < DimensionInfo.MinRasterHeight)
- gx_device_set_width_height(dev, dev->width,
- DimensionInfo.MinRasterHeight);
- if (dev->height > DimensionInfo.MaxRasterHeight)
- gx_device_set_width_height(dev, dev->width,
- DimensionInfo.MaxRasterHeight);
-
- /* Try to open a custom screen; if this fails, try to
- * rescale the colour cube and retry.
- */
-
- do
- {
- xdev -> screen = OpenScreenTags(NULL,
- SA_Depth, ScreenDepth,
- SA_Overscan, OSCAN_TEXT,
- SA_Quiet, TRUE,
- SA_Behind, TRUE,
- SA_DisplayID, Mode,
- SA_Colors, (ULONG)Colours,
- SA_AutoScroll, TRUE,
- SA_ShowTitle, FALSE,
- SA_Title, (ULONG)"Ghostscript Amiga output screen",
- SA_Width, dev->width,
- SA_Height, dev->height,
- TAG_DONE);
- if(!(xdev -> screen))
- {
- if(ScreenDepth < 2)
- break;
- else
- {
- ScreenDepth--;
-
- /* Check to see whether we will be able to
- * build a colour display or not.
- */
-
- while(cube_size >= 2)
- {
- if((max = cube_size * cube_size * cube_size) <= 1 << ScreenDepth)
- break;
- else
- cube_size--;
- }
-
- /* Got enough colours? */
-
- if(cube_size == 1 || ScreenDepth == 1)
- {
- /* Obviously not. */
-
- ScreenDepth = 1;
-
- set_mono_device((gx_device_amiga *)dev);
- }
- }
- }
- }
- while(!xdev -> screen);
-
- /* Did we succeed in opening the screen? */
-
- if(xdev -> screen)
- {
- /* OpenScreenTags above really shouldn't have changed these,
- * but better be safe...
- */
-
- gx_device_set_width_height(dev, xdev->screen->Width,
- xdev->screen->Height);
-
- xdev -> window = OpenWindowTags(NULL,
- WA_Left, 0,
- WA_Top, 0,
- WA_Width, dev -> width,
- WA_Height, dev -> height,
- WA_Backdrop, TRUE,
- WA_RMBTrap, TRUE,
- WA_Borderless, TRUE,
- WA_CustomScreen,(ULONG)(xdev -> screen),
- TAG_DONE);
- if(xdev -> window)
- {
- xdev -> rport = xdev -> window -> RPort;
- }
- else
- {
- xdev -> rport = &xdev -> screen -> RastPort;
- }
-
- /* Establish defaults. */
-
- DarkPen = 0;
- LightPen = 1;
-
- SetBPen(xdev -> rport,0);
- SetDrMd(xdev -> rport,JAM2);
-
- /* Create the temporary drawing area. */
-
- xdev -> temp_rport = CreateTempRPort(xdev -> rport);
- if(xdev -> temp_rport)
- {
- xdev -> temp_array = (UBYTE *)AllocVec((dev -> width + 15)
- & ~15, MEMF_ANY);
- if(xdev -> temp_array)
- {
- /* Colour output enabled? */
-
- if(xdev -> cube_size > 0)
- {
- LONG r,g,b,max = xdev -> cube_size - 1;
-
- i = 0;
-
- /* Build a suitable colour map. */
-
- if(GfxBase -> LibNode . lib_Version >= 39)
- {
- for(r = 0 ; r < xdev -> cube_size ; r++)
- {
- for(g = 0 ; g < xdev -> cube_size ; g++)
- {
- for(b = 0 ; b < xdev -> cube_size ; b++)
- SetRGB32(&xdev -> screen -> ViewPort,i++,SPREAD((255 * r) / max),SPREAD((255 * g) / max),SPREAD((255 * b) / max));
- }
- }
- }
- else
- {
- for(r = 0 ; r < xdev -> cube_size ; r++)
- {
- for(g = 0 ; g < xdev -> cube_size ; g++)
- {
- for(b = 0 ; b < xdev -> cube_size ; b++)
- SetRGB4(&xdev -> screen -> ViewPort,i++,(15 * r) / max,(15 * g) / max,(15 * b) / max);
- }
- }
- }
- }
- }
- else
- {
- eprintf("Ghostscript: failed to allocate temporary line\n");
-
- return_error(gs_error_unknownerror);
- }
- }
- else
- {
- eprintf("Ghostscript: failed to allocate temporary raster\n");
-
- return_error(gs_error_unknownerror);
- }
-
- amiga_set_pen(dev,DarkPen);
-
- return(0);
- }
- else
- eprintf("Ghostscript: failed to open screen\n");
- }
- else
- eprintf("Ghostscript: failed to get display mode information\n");
-
- return_error(gs_error_unknownerror);
- }
-
- /* amiga_output_page(gx_device *dev,int,int):
- *
- * Page is not `buffered', just bring screen/window
- * to the front.
- */
-
- private int
- amiga_output_page(gx_device *dev,int num_copies,int flush)
- {
- if(xdev -> screen)
- ScreenToFront(xdev -> screen);
- else
- {
- if(xdev -> window)
- WindowToFront(xdev -> window);
- }
-
- return(0);
- }
-
- /* amiga_close(gx_device *dev):
- *
- * Close the screen and free associated resources.
- */
-
- private int
- amiga_close(gx_device *dev)
- {
- if(xdev -> dispatcher)
- {
- const sigset_t trapped = sigmask(SIGINT);
- #ifdef IXEMUL
- sigprocmask(SIG_BLOCK,&trapped,NULL);
- #endif
-
- #ifndef __PPC__
- Forbid();
-
- Signal(xdev -> dispatcher,SIG_KILL);
-
- SetSignal(0,SIG_HANDSHAKE);
-
- Wait(SIG_HANDSHAKE);
-
- Permit();
- #else
- Signal(xdev -> dispatcher,SIG_KILL);
- #endif
-
- #ifdef IXEMUL
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- #endif
- }
-
- if(xdev -> temp_array)
- {
- FreeVec(xdev -> temp_array);
-
- xdev -> temp_array = NULL;
- }
-
- if(xdev -> pens)
- {
- LONG i;
-
- for(i = 0 ; i < xdev -> cube_size * xdev -> cube_size * xdev -> cube_size ; i++)
- {
- if(xdev -> pens[i] != -1)
- ReleasePen(xdev -> window -> WScreen -> ViewPort . ColorMap,xdev -> pens[i]);
- }
-
- FreeVec(xdev -> pens);
-
- xdev -> pens = NULL;
- }
-
- if(xdev -> temp_rport)
- {
- DeleteTempRPort(xdev -> temp_rport);
-
- xdev -> temp_rport = NULL;
- }
-
- if(xdev -> window)
- {
- CloseWindow(xdev -> window);
-
- xdev -> window = NULL;
- }
-
- DeleteScrollers(dev);
-
- if(xdev -> super_bitmap)
- {
- DeleteBitMap(xdev -> super_bitmap,FALSE);
-
- xdev -> super_bitmap = NULL;
- }
-
- if(xdev -> screen)
- {
- CloseScreen(xdev -> screen);
-
- xdev -> screen = NULL;
- }
-
- return(0);
- }
-
- /* amiga_fill_rectangle(gx_device *dev,int x,int y,int w,int h,gx_color_index color):
- *
- * Fill a rectangle with a given colour. This one is simple as it can
- * be done with the Amiga graphics primitives.
- */
-
- private int
- amiga_fill_rectangle(gx_device *dev,int x,int y,int w,int h,gx_color_index color)
- {
- fit_fill(dev, x, y, w, h);
- if(color != gx_no_color_index)
- {
- amiga_set_pen(dev,color);
-
- RectFill(xdev -> rport, x, y, (x + w - 1), (y + h - 1));
- }
-
- return(0);
- }
-
- /* amiga_copy_mono():
- *
- * Copy a monochrome image. This operation requires a bit of work as
- * we cannot simply blit the image into the bitmap.
- */
-
- private int
- amiga_copy_mono(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)
- {
- LONG i,j;
-
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
-
- if(zero == gx_no_color_index)
- {
- if(one != gx_no_color_index)
- {
- do
- {
- ReadPixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- for(i = sourcex, j = 0 ; i < sourcex + w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- xdev -> temp_array[j] = one;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
- }
- }
- else
- {
- if(one == gx_no_color_index)
- {
- do
- {
- ReadPixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- for(i = sourcex, j = 0 ; i < w + sourcex ; i++, j++)
- {
- if(!(base[i >> 3] & shift[i & 7]))
- xdev -> temp_array[j] = zero;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = 0 ; i < w + sourcex ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- xdev -> temp_array[j] = one;
- else
- xdev -> temp_array[j] = zero;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
- }
- }
-
- return(0);
- }
-
- /* amiga_copy_color():
- *
- * Copy a color image (oh well...). This is just the same as the
- * copy_mono() routine.
- */
-
- private int
- amiga_copy_color(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- LONG i,j;
-
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
-
- do
- {
- for(i = sourcex, j = 0 ; i < w + sourcex ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- xdev -> temp_array[j] = DarkPen;
- else
- xdev -> temp_array[j] = LightPen;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
-
- return(0);
- }
-
- /* amiga_draw_line(gx_device *dev,int x0,int y0,int x1,int y1,gx_color_index color):
- *
- * Draw a line between two points. This one is easy as it can be done
- * with the Amiga graphics primitives, the only glitch is having to reset
- * the last dot to its original colour.
- */
-
- private int
- amiga_draw_line(gx_device *dev,int x0,int y0,int x1,int y1,gx_color_index color)
- {
- if(color != gx_no_color_index && (x0 != x1 || y0 != y1))
- {
- LONG pen;
-
- pen = ReadPixel(xdev -> rport,x1,y1);
-
- amiga_set_pen(dev,color);
-
- Move(xdev -> rport,x0,y0);
- Draw(xdev -> rport,x1,y1);
-
- if(pen == color)
- {
- amiga_set_pen(dev,pen);
-
- WritePixel(xdev -> rport,x1,y1);
- }
- }
-
- return(0);
- }
-
- /* amiga_copy_mono_raw():
- *
- * Copy a monochrome image to a bitmap. Just watch the
- * astounding number of case switches.
- */
-
- private int
- amiga_copy_mono_raw(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)
- {
- LONG i,j,modulo = xdev -> rport -> BitMap -> BytesPerRow;
- UBYTE *line;
-
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
-
- w += sourcex;
-
- line = xdev -> rport -> BitMap -> Planes[0] + y * xdev -> rport -> BitMap -> BytesPerRow;
-
- if(zero == gx_no_color_index)
- {
- if(one != gx_no_color_index)
- {
- if(one)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] |= shift[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] &= masks[j & 7];
- }
- base += raster;
- line += modulo;
- }
- while(--h);
- }
- }
- }
- else
- {
- if(one == gx_no_color_index)
- {
- if(zero)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(!(base[i >> 3] & shift[i & 7]))
- line[j >> 3] |= shift[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(!(base[i >> 3] & shift[i & 7]))
- line[j >> 3] &= masks[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- }
- else
- {
- if(one)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] |= shift[j & 7];
- else
- line[j >> 3] &= masks[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] &= masks[j & 7];
- else
- line[j >> 3] |= shift[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- }
- }
-
- return(0);
- }
-
- /* amiga_copy_color_raw():
- *
- * Copy a color image (oh well...). This is just the same as the
- * copy_mono() routine.
- */
-
- private int
- amiga_copy_color_raw(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- LONG i,j,modulo = xdev -> rport -> BitMap -> BytesPerRow;
- UBYTE *line;
-
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
-
- line = xdev -> rport -> BitMap -> Planes[0] + y * xdev -> rport -> BitMap -> BytesPerRow;
-
- w += sourcex;
-
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] |= shift[j & 7];
- else
- line[j >> 3] &= masks[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
-
- return(0);
- }
-
- /* amiga_fill_rectangle_raw():
- *
- * Fill a rectangular area in a bitmap.
- */
-
- private int
- amiga_fill_rectangle_raw(gx_device *dev,int x,int y,int w,int h,gx_color_index color)
- {
- fit_fill(dev, x, y, w, h);
-
- if(color != gx_no_color_index)
- {
- UBYTE *line,startmask,endmask;
- LONG right,mid,modulo = xdev -> rport -> BitMap -> BytesPerRow;
-
- right = x + w;
- mid = (right >> 3) - (x >> 3);
- line = xdev -> rport -> BitMap -> Planes[0] + y * xdev -> rport -> BitMap -> BytesPerRow + (x >> 3);
-
- x &= 7;
- right &= 7;
-
- if(color)
- {
- startmask = 0xFF >> x;
- endmask = ~(0xFF >> right);
-
- if(mid)
- {
- UBYTE *ptr;
- int i;
-
- do
- {
- ptr = line;
-
- *ptr++ |= startmask;
-
- i = mid;
-
- while(--i > 0)
- *ptr++ = 0xFF;
-
- *ptr |= endmask;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- startmask &= endmask;
-
- do
- {
- *line |= startmask;
-
- line += modulo;
- }
- while(--h);
- }
- }
- else
- {
- startmask = ~(0xFF >> x);
- endmask = 0xFF >> right;
-
- if(mid)
- {
- UBYTE *ptr;
- LONG i;
-
- do
- {
- ptr = line;
-
- *ptr++ &= startmask;
-
- i = mid;
-
- while(--i > 0)
- *ptr++ = 0x00;
-
- *ptr &= endmask;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- startmask |= endmask;
-
- do
- {
- *line &= startmask;
-
- line += modulo;
- }
- while(--h);
- }
- }
- }
-
- return(0);
- }
-
- /* amiga_draw_line_raw():
- *
- * Draw a hair line, your basic DDA algorithm;
- * keep your fingers crossed.
- */
-
- private int
- amiga_draw_line_raw(gx_device *dev,int x,int y,int x1,int y1,gx_color_index color)
- {
- if(color != gx_no_color_index && (x != x1 || y != y1))
- {
- short xstep,ystep,dx,dy,diff,modulo;
- UBYTE *line,*plane,pen;
- LONG last;
-
- modulo = xdev -> rport -> BitMap -> BytesPerRow;
- plane = xdev -> rport -> BitMap -> Planes[0];
-
- line = &plane[y1 * modulo];
- last = y1;
- pen = line[x1 >> 3] & (x1 & 7);
-
- dx = x1 - x;
- dy = y1 - y;
-
- if(dx < 0)
- {
- dx = -dx;
- dy = -dy;
-
- x = x1;
- y = y1;
- }
-
- if(y != last)
- line = &plane[(last = y) * modulo];
-
- if(color)
- {
- line[x >> 3] |= shift[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(!pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- else
- {
- line[x >> 3] &= masks[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= pen;
- }
- }
- }
-
- return(0);
- }
-
- /* amiga_open_ilbm(gx_device *dev):
- *
- * Open the ilbm device.
- */
-
- private int
- amiga_open_ilbm(gx_device *dev)
- {
- xdev -> rport = (struct RastPort *)AllocVec(sizeof(struct RastPort),MEMF_ANY);
- if(xdev -> rport)
- {
- InitRastPort(xdev -> rport);
-
- xdev -> bitmap = (struct BitMap *)AllocVec(sizeof(struct BitMap),MEMF_ANY);
- if(xdev -> bitmap)
- {
- InitBitMap(xdev -> bitmap,1,xdev -> width,xdev -> height);
-
- xdev -> bitplane = AllocVec(xdev -> bitmap -> Rows * xdev -> bitmap -> BytesPerRow,MEMF_ANY | MEMF_CLEAR);
- if(xdev -> bitplane)
- {
- xdev -> bitmap -> Planes[0] = xdev -> bitplane;
- xdev -> rport -> BitMap = xdev -> bitmap;
- xdev -> page_count = 1;
-
- DarkPen = 0;
- LightPen = 1;
-
- return(0);
- }
- else
- {
- char buffer[256];
-
- sprintf(buffer,"Ghostscript: failed to allocate raster "
- "(wanted %ld, largest %ld)\n",
- (long)(xdev->bitmap->Rows * xdev->bitmap->BytesPerRow),
- AvailMem(MEMF_ANY | MEMF_LARGEST));
-
- eprintf(buffer);
- }
- }
- else
- eprintf("Ghostscript: failed to allocate bitmap\n");
- }
- else
- eprintf("Ghostscript: failed to allocate raster port\n");
-
- return_error(gs_error_unknownerror);
- }
-
- /* amiga_output_page_ilbm(gx_device *dev,int,int):
- *
- * Send a bitmap to an IFF-ILBM file.
- */
-
- private int
- amiga_output_page_ilbm(gx_device *dev,int num_copies,int flush)
- {
- const sigset_t trapped = sigmask(SIGINT);
- char buffer[270];
-
- sprintf(buffer,"%s_%04d.ilbm",xdev -> file_name,xdev -> page_count);
-
- fprintf(stdout,"\n\033[ASaving page Nº%d to \"%s\"...\033[K",xdev -> page_count,buffer);
- fflush(stdout);
- #ifdef IXEMUL
- sigprocmask(SIG_BLOCK,&trapped,NULL);
- #endif
- if(SaveBitMap(buffer,xdev -> bitmap,xdev -> width,xdev -> height,(UWORD)xdev -> x_pixels_per_inch,xdev -> y_pixels_per_inch))
- {
- fprintf(stdout,"\n\033[APage saved to file \"%s\".\033[K\n",buffer);
-
- xdev -> page_count++;
-
- #ifdef IXEMUL
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- #endif
-
- return (0);
- }
- else
- {
- eprintf("\n\033[AGhostscript: error saving page\033[K");
-
- #ifdef IXEMUL
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- #endif
-
- return_error(gs_error_unknownerror);
- }
- }
-
- /* amiga_close_ilbm(gx_device *dev):
- *
- * Close the ilbm driver.
- */
-
- private int
- amiga_close_ilbm(gx_device *dev)
- {
- if(xdev -> bitplane)
- {
- FreeVec(xdev -> bitplane);
-
- xdev -> bitplane = NULL;
- }
-
- if(xdev -> bitmap)
- {
- FreeVec(xdev -> bitmap);
-
- xdev -> bitmap = NULL;
- }
-
- if(xdev -> rport)
- {
- FreeVec(xdev -> rport);
-
- xdev -> rport = NULL;
- }
-
- return(0);
- }
-
- private int
- amiga_get_params(gx_device *dev,gs_param_list *plist)
- {
- int code = gx_default_get_params(dev,plist);
- gs_param_string dms;
- gs_param_string ofs;
-
- dms.data = (const byte *)xdev->display_mode,
- dms.size = strlen(xdev->display_mode),
- dms.persistent = false;
-
- ofs.data = (const byte *)xdev->file_name,
- ofs.size = strlen(xdev->file_name),
- ofs.persistent = false;
-
- /* Transmit the values. */
-
- if (code < 0
- || (code = param_write_string(plist, "DisplayMode", &dms)) < 0
- || (code = param_write_string(plist, "OutputFile", &ofs)) < 0
- )
- return code;
-
- return 0;
- }
-
- private int
- amiga_put_params(gx_device *dev,gs_param_list *plist)
- {
- int ecode = 0;
- int code;
- const char /*_ds*/ *param_name;
- gs_param_string dms;
- gs_param_string ofs;
- gs_param_float_array hwra;
- gs_param_int_array hwsa;
-
- switch ( code = param_read_string(plist, (param_name = "DisplayMode"), &dms) )
- {
- case 0:
- if ( dms.size >= (DISPLAYNAMELEN + 1) ) /* see displayinfo.h */
- ecode = gs_note_error(gs_error_limitcheck);
- else if (dms.size >= 11 && '0' == dms.data[0] /* correct hex val? */
- && ('x' == dms.data[1] || 'X' == dms.data[1]))
- ecode = gs_note_error(gs_error_limitcheck);
- else
- break;
- goto mide;
- default:
- ecode = code;
- mide: param_signal_error(plist, param_name, ecode);
- case 1:
- dms.data = 0;
- break;
- }
-
- switch ( code = param_read_string(plist, (param_name = "OutputFile"), &ofs) )
- {
- case 0:
- if ( ofs.size >= 256 )
- ecode = gs_note_error(gs_error_limitcheck);
- else
- break;
- goto ofe;
- default:
- ecode = code;
- ofe: param_signal_error(plist, param_name, ecode);
- case 1:
- ofs.data = 0;
- break;
- }
-
- /* Because the resolution is set after the device has been opened we need
- * to detect wether user has set -g and/or -r at the command line in
- * order to prevent wrong computing of HWSize/MediaSize from HWResolution.
- * We therefore double the code from gsdparam.c and set global variables
- * accordingly.
- * The following code between [BEGIN] and [END ] should always double the
- * one in gsdparam.c except those two lines marked with [ADDED].
- */
-
- /* [BEGIN]: doubled code from gsdparam.c */
- #define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
- switch ( code = pread(plist, (param_name = pname), &(pa)) )\
- {\
- case 0:\
- if ( (pa).size != psize )\
- ecode = gs_note_error(gs_error_rangecheck);\
- else {
- /* The body of the processing code goes here. */
- /* If it succeeds, it should do a 'break'; */
- /* if it fails, it should set ecode and fall through. */
- #define END_ARRAY_PARAM(pa, e)\
- }\
- goto e;\
- default:\
- ecode = code;\
- e: param_signal_error(plist, param_name, ecode);\
- case 1:\
- (pa).data = 0; /* mark as not filled */\
- }
-
- /*
- * The HWResolution, HWSize, and MediaSize parameters interact in
- * the following way:
- * 1. Setting HWResolution recomputes HWSize from MediaSize.
- * 2. Setting HWSize recomputes MediaSize from HWResolution.
- * 3. Setting MediaSize recomputes HWSize from HWResolution.
- * If more than one parameter is being set, we apply these rules
- * in the order 1, 2, 3. This does the right thing in the most
- * common case of setting more than one parameter, namely,
- * setting both HWResolution and HWSize.
- */
-
- BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre)
- if ( hwra.data[0] <= 0 || hwra.data[1] <= 0 )
- ecode = gs_note_error(gs_error_rangecheck);
- else
- {
- ResolutionSwitch = TRUE; /* [ADDED]: user has set -r */
- break;
- }
- END_ARRAY_PARAM(hwra, hwre)
-
- BEGIN_ARRAY_PARAM(param_read_int_array, "HWSize", hwsa, 2, hwsa)
- /* We need a special check to handle the nullpage device, */
- /* whose size is legitimately [0 0]. */
- if ( (hwsa.data[0] <= 0 && hwsa.data[0] != dev->width) ||
- (hwsa.data[1] <= 0 && hwsa.data[1] != dev->height)
- )
- ecode = gs_note_error(gs_error_rangecheck);
- #define max_coord (max_fixed / fixed_1)
- #if max_coord < max_int
- else if ( hwsa.data[0] > max_coord || hwsa.data[1] > max_coord )
- ecode = gs_note_error(gs_error_limitcheck);
- #endif
- #undef max_coord
- else
- {
- GeometrySwitch = TRUE; /* [ADDED]: user has set -g */
- break;
- }
- END_ARRAY_PARAM(hwsa, hwse)
- /* [END]: doubled code from gsdparam.c */
-
- if (ecode < 0)
- return (ecode);
- code = gx_default_put_params(dev,plist);
- if (code < 0)
- return (code);
-
- if ( dms.data != 0 )
- { if ( dev->is_open )
- gs_closedevice(dev);
- memcpy(xdev->display_mode, dms.data, dms.size);
- xdev->display_mode[dms.size] = 0;
- }
-
- if ( ofs.data != 0 )
- {
- memcpy(xdev->file_name, ofs.data, ofs.size);
- xdev->file_name[ofs.size] = 0;
- }
-
- if (code < 0)
- return (code);
- return (0);
- }
-
- /* amiga_color_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue):
- *
- * Turn an RGB colour into a pen index.
- */
-
- private gx_color_index
- amiga_color_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue)
- {
- LONG max = xdev -> cube_size - 1,r,g,b;
-
- r = (max * red) / gx_max_color_value;
- g = (max * green) / gx_max_color_value;
- b = (max * blue) / gx_max_color_value;
-
- return((r * xdev -> cube_size + g) * xdev -> cube_size + b);
- }
-
- /* amiga_color_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3]):
- *
- * Turn a pen index into RGB colour values.
- */
-
- private int
- amiga_color_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3])
- {
- LONG i,value,max = xdev -> cube_size - 1;
-
- for(i = 2 ; i >= 0 ; i--)
- {
- value = color % xdev -> cube_size;
-
- rgb[i] = (gx_max_color_value * value) / max;
-
- color /= xdev -> cube_size;
- }
-
- return(0);
- }
-
- /* amiga_color_map_rgb_color_pen(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue):
- *
- * Turn an RGB colour into a pen index; this routine takes remapped
- * pens into account.
- */
-
- private gx_color_index
- amiga_color_map_rgb_color_pen(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue)
- {
- LONG max = xdev -> cube_size - 1,r,g,b;
-
- r = (max * red) / gx_max_color_value;
- g = (max * green) / gx_max_color_value;
- b = (max * blue) / gx_max_color_value;
-
- return(xdev -> pens[(r * xdev -> cube_size + g) * xdev -> cube_size + b]);
- }
-
- /* amiga_color_map_color_rgb_pen(gx_device *dev,gx_color_index color,gx_color_value rgb[3]):
- *
- * Turn a pen index into RGB colour values; this routine takes remapped
- * pens into account.
- */
-
- private int
- amiga_color_map_color_rgb_pen(gx_device *dev,gx_color_index color,gx_color_value rgb[3])
- {
- LONG i,value,max = xdev -> cube_size - 1;
-
- /* Find the matching pen... */
-
- for(i = 0 ; i < xdev -> cube_size * xdev -> cube_size * xdev -> cube_size ; i++)
- {
- if(xdev -> pens[i] == color)
- {
- color = i;
-
- break;
- }
- }
-
- for(i = 2 ; i >= 0 ; i--)
- {
- value = color % xdev -> cube_size;
-
- rgb[i] = (gx_max_color_value * value) / max;
-
- color /= xdev -> cube_size;
- }
-
- return(0);
- }
-
- /* amiga_copy_color8():
- *
- * Copy a color image, the source is guaranteed to consist of
- * one byte per colour.
- */
-
- private int
- amiga_copy_color8(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
-
- base += sourcex;
-
- if(w > xdev -> width)
- w = xdev -> width;
-
- do
- {
- CopyMem((UBYTE *)base,xdev -> temp_array,w);
-
- WritePixelLine8(xdev -> rport,x,y++,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
- }
- while(--h);
-
- return(0);
- }
-
- /* amiga_copy_mono_raw_color():
- *
- * Copy a monochrome image to a bitmap.
- */
-
- private int
- amiga_copy_mono_raw_color(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)
- {
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
-
- if(zero != gx_no_color_index && one != gx_no_color_index)
- {
- PLANEPTR line[12];
- LONG i,j,k,modulo = xdev -> rport -> BitMap -> BytesPerRow,depth = xdev -> rport -> BitMap -> Depth;
-
- for(i = 0 ; i < depth ; i++)
- line[i] = xdev -> rport -> BitMap -> Planes[i] + y * modulo;
-
- w += sourcex;
-
- if(zero == gx_no_color_index)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(one & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- }
-
- base += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
- }
- else
- {
- if(one == gx_no_color_index)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(zero & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- }
-
- base += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(one & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- else
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(zero & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- }
-
- base += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
- }
- }
- }
-
- return(0);
- }
-
- /* amiga_copy_color_raw_color16():
- *
- * Copy a color image, the source data is guaranteed to consist
- * of one word per colour.
- */
-
- private int
- amiga_copy_color_raw_color16(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- PLANEPTR line[12];
- LONG i,j,k;
- LONG modulo = xdev->rport->BitMap->BytesPerRow;
- LONG depth = xdev->rport->BitMap->Depth;
- UWORD *wordbase = (UWORD *)base;
-
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
-
- for(i = 0 ; i < depth ; i++)
- line[i] = xdev -> rport -> BitMap -> Planes[i] + y * modulo;
-
- w += sourcex;
-
- raster /= 2;
-
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(wordbase[i] & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
-
- wordbase += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
-
- return(0);
- }
-
- /* amiga_fill_rectangle_raw_color():
- *
- * Fill a rectangular area in a bitmap.
- */
-
- private int
- amiga_fill_rectangle_raw_color(gx_device *dev,int x,int y,int w,int h,gx_color_index color)
- {
- fit_fill(dev, x, y, w, h);
-
- if(color != gx_no_color_index)
- {
- PLANEPTR line[12];
- LONG i,j,right,mid,modulo = xdev -> rport -> BitMap -> BytesPerRow,depth = xdev -> rport -> BitMap -> Depth;
-
- for(i = 0 ; i < depth ; i++)
- line[i] = xdev -> rport -> BitMap -> Planes[i] + y * modulo + (x >> 3);
-
- right = x + w;
- mid = (right >> 3) - (x >> 3);
-
- x &= 7;
- right &= 7;
-
- if(mid)
- {
- UBYTE *ptr;
-
- do
- {
- for(j = 0 ; j < depth ; j++)
- {
- ptr = line[j];
-
- i = mid;
-
- if(color & (1 << j))
- {
- *ptr++ |= 0xFF >> x;
-
- while(--i > 0)
- *ptr++ = 0xFF;
-
- *ptr |= ~(0xFF >> right);
- }
- else
- {
- *ptr++ &= ~(0xFF >> x);
-
- while(--i > 0)
- *ptr++ = 0x00;
-
- *ptr &= 0xFF >> right;
- }
-
- line[j] += modulo;
- }
- }
- while(--h);
- }
- else
- {
- UBYTE one_mask = (0xFF >> x) & ~(0xFF >> right),
- zero_mask = ~(0xFF >> x) | (0xFF >> right);
-
- do
- {
- for(j = 0 ; j < depth ; j++)
- {
- if(color & (1 << j))
- *line[j] |= one_mask;
- else
- *line[j] &= zero_mask;
-
- line[j] += modulo;
- }
- }
- while(--h);
- }
- }
-
- return(0);
- }
-
- /* amiga_draw_line_raw_color():
- *
- * Draw a hair line, your basic DDA algorithm;
- * keep your fingers crossed.
- */
-
- private int
- amiga_draw_line_raw_color(gx_device *dev,int x,int y,int x1,int y1,gx_color_index color)
- {
- if(color != gx_no_color_index && (x != x1 || y != y1))
- {
- LONG xstep,ystep,dx,dy,diff,modulo;
- UBYTE *line,*plane,pen;
- LONG last,i,orig_x = x,orig_y = y;
-
- modulo = xdev -> rport -> BitMap -> BytesPerRow;
-
- for(i = 0 ; i < xdev -> rport -> BitMap -> Depth ; i++)
- {
- plane = xdev -> rport -> BitMap -> Planes[i];
- line = &plane[y1 * modulo];
- last = y1;
- pen = line[x1 >> 3] & (x1 & 7);
- x = orig_x;
- y = orig_y;
-
- dx = x1 - x;
- dy = y1 - y;
-
- if(dx < 0)
- {
- dx = -dx;
- dy = -dy;
-
- x = x1;
- y = y1;
- }
-
- if(y != last)
- line = &plane[(last = y) * modulo];
-
- if(color & (1 << i))
- {
- line[x >> 3] |= shift[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(!pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- else
- {
- line[x >> 3] &= masks[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= pen;
- }
- }
- }
- }
-
- return(0);
- }
-